4 Copyright (C) Andrew Tridgell 2007
5 Copyright (C) Ronnie Sahlberg 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/>.
24 #include "lib/util/dlinklist.h"
25 #include "system/network.h"
26 #include "system/filesys.h"
27 #include "system/locale.h"
29 #include "../include/ctdb_private.h"
30 #include "lib/util/dlinklist.h"
35 allocate a packet for use in client<->daemon communication
37 struct ctdb_req_header *_ctdbd_allocate_pkt(struct ctdb_context *ctdb,
39 enum ctdb_operation operation,
40 size_t length, size_t slength,
44 struct ctdb_req_header *hdr;
46 length = MAX(length, slength);
47 size = (length+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
49 hdr = (struct ctdb_req_header *)talloc_zero_size(mem_ctx, size);
51 DEBUG(DEBUG_ERR,("Unable to allocate packet for operation %u of length %u\n",
52 operation, (unsigned)length));
55 talloc_set_name_const(hdr, type);
57 hdr->operation = operation;
58 hdr->ctdb_magic = CTDB_MAGIC;
59 hdr->ctdb_version = CTDB_VERSION;
60 hdr->srcnode = ctdb->pnn;
62 hdr->generation = ctdb->vnn_map->generation;
69 local version of ctdb_call
71 int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
72 struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx,
73 TDB_DATA *data, bool updatetdb, uint32_t caller)
75 struct ctdb_call_info *c;
76 struct ctdb_registered_call *fn;
77 struct ctdb_context *ctdb = ctdb_db->ctdb;
79 c = talloc(ctdb, struct ctdb_call_info);
80 CTDB_NO_MEMORY(ctdb, c);
83 c->call_data = &call->call_data;
84 c->record_data.dptr = talloc_memdup(c, data->dptr, data->dsize);
85 c->record_data.dsize = data->dsize;
86 CTDB_NO_MEMORY(ctdb, c->record_data.dptr);
92 for (fn=ctdb_db->calls;fn;fn=fn->next) {
93 if (fn->id == call->call_id) break;
96 ctdb_set_error(ctdb, "Unknown call id %u\n", call->call_id);
101 if (fn->fn(c) != 0) {
102 ctdb_set_error(ctdb, "ctdb_call %u failed\n", call->call_id);
107 /* we need to force the record to be written out if this was a remote access */
108 if (header->laccessor != caller) {
111 header->laccessor = caller;
114 /* we need to force the record to be written out if this was a remote access,
115 so that the lacount is updated */
116 if (c->new_data == NULL && header->laccessor != ctdb->pnn) {
117 c->new_data = &c->record_data;
120 if (c->new_data && updatetdb) {
121 /* XXX check that we always have the lock here? */
122 if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
123 ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
130 call->reply_data = *c->reply_data;
132 talloc_steal(call, call->reply_data.dptr);
133 talloc_set_name_const(call->reply_data.dptr, __location__);
135 call->reply_data.dptr = NULL;
136 call->reply_data.dsize = 0;
138 call->status = c->status;
147 queue a packet for sending from client to daemon
149 static int ctdb_client_queue_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
151 return ctdb_queue_send(ctdb->daemon.queue, (uint8_t *)hdr, hdr->length);
156 called when a CTDB_REPLY_CALL packet comes in in the client
158 This packet comes in response to a CTDB_REQ_CALL request packet. It
159 contains any reply data from the call
161 static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
163 struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
164 struct ctdb_client_call_state *state;
166 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_call_state);
168 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
172 if (hdr->reqid != state->reqid) {
173 /* we found a record but it was the wrong one */
174 DEBUG(DEBUG_ERR, ("Dropped client call reply with reqid:%u\n",hdr->reqid));
178 state->call->reply_data.dptr = c->data;
179 state->call->reply_data.dsize = c->datalen;
180 state->call->status = c->status;
182 talloc_steal(state, c);
184 state->state = CTDB_CALL_DONE;
186 if (state->async.fn) {
187 state->async.fn(state);
191 static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
194 this is called in the client, when data comes in from the daemon
196 void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
198 struct ctdb_context *ctdb = talloc_get_type(args, struct ctdb_context);
199 struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
202 /* place the packet as a child of a tmp_ctx. We then use
203 talloc_free() below to free it. If any of the calls want
204 to keep it, then they will steal it somewhere else, and the
205 talloc_free() will be a no-op */
206 tmp_ctx = talloc_new(ctdb);
207 talloc_steal(tmp_ctx, hdr);
210 DEBUG(DEBUG_CRIT,("Daemon has exited - shutting down client\n"));
214 if (cnt < sizeof(*hdr)) {
215 DEBUG(DEBUG_CRIT,("Bad packet length %u in client\n", (unsigned)cnt));
218 if (cnt != hdr->length) {
219 ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
220 (unsigned)hdr->length, (unsigned)cnt);
224 if (hdr->ctdb_magic != CTDB_MAGIC) {
225 ctdb_set_error(ctdb, "Non CTDB packet rejected in client\n");
229 if (hdr->ctdb_version != CTDB_VERSION) {
230 ctdb_set_error(ctdb, "Bad CTDB version 0x%x rejected in client\n", hdr->ctdb_version);
234 switch (hdr->operation) {
235 case CTDB_REPLY_CALL:
236 ctdb_client_reply_call(ctdb, hdr);
239 case CTDB_REQ_MESSAGE:
240 ctdb_request_message(ctdb, hdr);
243 case CTDB_REPLY_CONTROL:
244 ctdb_client_reply_control(ctdb, hdr);
248 DEBUG(DEBUG_CRIT,("bogus operation code:%u\n",hdr->operation));
252 talloc_free(tmp_ctx);
256 connect to a unix domain socket
258 int ctdb_socket_connect(struct ctdb_context *ctdb)
260 struct sockaddr_un addr;
262 memset(&addr, 0, sizeof(addr));
263 addr.sun_family = AF_UNIX;
264 strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path));
266 ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
267 if (ctdb->daemon.sd == -1) {
268 DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
272 if (connect(ctdb->daemon.sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
273 close(ctdb->daemon.sd);
274 ctdb->daemon.sd = -1;
275 DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
279 set_nonblocking(ctdb->daemon.sd);
280 set_close_on_exec(ctdb->daemon.sd);
282 ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
284 ctdb_client_read_cb, ctdb, "to-ctdbd");
289 struct ctdb_record_handle {
290 struct ctdb_db_context *ctdb_db;
293 struct ctdb_ltdb_header header;
298 make a recv call to the local ctdb daemon - called from client context
300 This is called when the program wants to wait for a ctdb_call to complete and get the
301 results. This call will block unless the call has already completed.
303 int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
309 while (state->state < CTDB_CALL_DONE) {
310 event_loop_once(state->ctdb_db->ctdb->ev);
312 if (state->state != CTDB_CALL_DONE) {
313 DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
318 if (state->call->reply_data.dsize) {
319 call->reply_data.dptr = talloc_memdup(state->ctdb_db,
320 state->call->reply_data.dptr,
321 state->call->reply_data.dsize);
322 call->reply_data.dsize = state->call->reply_data.dsize;
324 call->reply_data.dptr = NULL;
325 call->reply_data.dsize = 0;
327 call->status = state->call->status;
337 destroy a ctdb_call in client
339 static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
341 ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
346 construct an event driven local ctdb_call
348 this is used so that locally processed ctdb_call requests are processed
349 in an event driven manner
351 static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
352 struct ctdb_call *call,
353 struct ctdb_ltdb_header *header,
356 struct ctdb_client_call_state *state;
357 struct ctdb_context *ctdb = ctdb_db->ctdb;
360 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
361 CTDB_NO_MEMORY_NULL(ctdb, state);
362 state->call = talloc_zero(state, struct ctdb_call);
363 CTDB_NO_MEMORY_NULL(ctdb, state->call);
365 talloc_steal(state, data->dptr);
367 state->state = CTDB_CALL_DONE;
368 *(state->call) = *call;
369 state->ctdb_db = ctdb_db;
371 ret = ctdb_call_local(ctdb_db, state->call, header, state, data, true, ctdb->pnn);
373 DEBUG(DEBUG_DEBUG,("ctdb_call_local() failed, ignoring return code %d\n", ret));
380 make a ctdb call to the local daemon - async send. Called from client context.
382 This constructs a ctdb_call request and queues it for processing.
383 This call never blocks.
385 struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
386 struct ctdb_call *call)
388 struct ctdb_client_call_state *state;
389 struct ctdb_context *ctdb = ctdb_db->ctdb;
390 struct ctdb_ltdb_header header;
394 struct ctdb_req_call *c;
396 /* if the domain socket is not yet open, open it */
397 if (ctdb->daemon.sd==-1) {
398 ctdb_socket_connect(ctdb);
401 ret = ctdb_ltdb_lock(ctdb_db, call->key);
403 DEBUG(DEBUG_ERR,(__location__ " Failed to get chainlock\n"));
407 ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
409 if ((call->flags & CTDB_IMMEDIATE_MIGRATION) && (header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
413 if (ret == 0 && header.dmaster == ctdb->pnn) {
414 state = ctdb_client_call_local_send(ctdb_db, call, &header, &data);
415 talloc_free(data.dptr);
416 ctdb_ltdb_unlock(ctdb_db, call->key);
420 ctdb_ltdb_unlock(ctdb_db, call->key);
421 talloc_free(data.dptr);
423 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
425 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state\n"));
428 state->call = talloc_zero(state, struct ctdb_call);
429 if (state->call == NULL) {
430 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state->call\n"));
434 len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
435 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CALL, len, struct ctdb_req_call);
437 DEBUG(DEBUG_ERR, (__location__ " failed to allocate packet\n"));
441 state->reqid = ctdb_reqid_new(ctdb, state);
442 state->ctdb_db = ctdb_db;
443 talloc_set_destructor(state, ctdb_client_call_destructor);
445 c->hdr.reqid = state->reqid;
446 c->flags = call->flags;
447 c->db_id = ctdb_db->db_id;
448 c->callid = call->call_id;
450 c->keylen = call->key.dsize;
451 c->calldatalen = call->call_data.dsize;
452 memcpy(&c->data[0], call->key.dptr, call->key.dsize);
453 memcpy(&c->data[call->key.dsize],
454 call->call_data.dptr, call->call_data.dsize);
455 *(state->call) = *call;
456 state->call->call_data.dptr = &c->data[call->key.dsize];
457 state->call->key.dptr = &c->data[0];
459 state->state = CTDB_CALL_WAIT;
462 ctdb_client_queue_pkt(ctdb, &c->hdr);
469 full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
471 int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
473 struct ctdb_client_call_state *state;
475 state = ctdb_call_send(ctdb_db, call);
476 return ctdb_call_recv(state, call);
481 tell the daemon what messaging srvid we will use, and register the message
482 handler function in the client
484 int ctdb_client_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid,
485 ctdb_msg_fn_t handler,
492 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_REGISTER_SRVID, 0,
493 tdb_null, NULL, NULL, &status, NULL, NULL);
494 if (res != 0 || status != 0) {
495 DEBUG(DEBUG_ERR,("Failed to register srvid %llu\n", (unsigned long long)srvid));
499 /* also need to register the handler with our own ctdb structure */
500 return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
504 tell the daemon we no longer want a srvid
506 int ctdb_client_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid, void *private_data)
511 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_DEREGISTER_SRVID, 0,
512 tdb_null, NULL, NULL, &status, NULL, NULL);
513 if (res != 0 || status != 0) {
514 DEBUG(DEBUG_ERR,("Failed to deregister srvid %llu\n", (unsigned long long)srvid));
518 /* also need to register the handler with our own ctdb structure */
519 ctdb_deregister_message_handler(ctdb, srvid, private_data);
525 send a message - from client context
527 int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t pnn,
528 uint64_t srvid, TDB_DATA data)
530 struct ctdb_req_message *r;
533 len = offsetof(struct ctdb_req_message, data) + data.dsize;
534 r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
535 len, struct ctdb_req_message);
536 CTDB_NO_MEMORY(ctdb, r);
538 r->hdr.destnode = pnn;
540 r->datalen = data.dsize;
541 memcpy(&r->data[0], data.dptr, data.dsize);
543 res = ctdb_client_queue_pkt(ctdb, &r->hdr);
554 cancel a ctdb_fetch_lock operation, releasing the lock
556 static int fetch_lock_destructor(struct ctdb_record_handle *h)
558 ctdb_ltdb_unlock(h->ctdb_db, h->key);
563 force the migration of a record to this node
565 static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
567 struct ctdb_call call;
569 call.call_id = CTDB_NULL_FUNC;
571 call.flags = CTDB_IMMEDIATE_MIGRATION;
572 return ctdb_call(ctdb_db, &call);
576 try to fetch a readonly copy of a record
579 ctdb_client_fetch_readonly(struct ctdb_db_context *ctdb_db, TDB_DATA key, TALLOC_CTX *mem_ctx, struct ctdb_ltdb_header **hdr, TDB_DATA *data)
583 struct ctdb_call call;
586 call.call_id = CTDB_FETCH_WITH_HEADER_FUNC;
587 call.call_data.dptr = NULL;
588 call.call_data.dsize = 0;
590 call.flags = CTDB_WANT_READONLY;
591 ret = ctdb_call(ctdb_db, &call);
596 if (call.reply_data.dsize < sizeof(struct ctdb_ltdb_header)) {
600 *hdr = talloc_memdup(mem_ctx, &call.reply_data.dptr[0], sizeof(struct ctdb_ltdb_header));
602 talloc_free(call.reply_data.dptr);
606 data->dsize = call.reply_data.dsize - sizeof(struct ctdb_ltdb_header);
607 data->dptr = talloc_memdup(mem_ctx, &call.reply_data.dptr[sizeof(struct ctdb_ltdb_header)], data->dsize);
608 if (data->dptr == NULL) {
609 talloc_free(call.reply_data.dptr);
618 get a lock on a record, and return the records data. Blocks until it gets the lock
620 struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
621 TDB_DATA key, TDB_DATA *data)
624 struct ctdb_record_handle *h;
627 procedure is as follows:
629 1) get the chain lock.
630 2) check if we are dmaster
631 3) if we are the dmaster then return handle
632 4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
634 5) when we get the reply, goto (1)
637 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
642 h->ctdb_db = ctdb_db;
644 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
645 if (h->key.dptr == NULL) {
651 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize,
652 (const char *)key.dptr));
655 /* step 1 - get the chain lock */
656 ret = ctdb_ltdb_lock(ctdb_db, key);
658 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
663 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
665 talloc_set_destructor(h, fetch_lock_destructor);
667 ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
669 /* when torturing, ensure we test the remote path */
670 if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
672 h->header.dmaster = (uint32_t)-1;
676 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
678 if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
679 ctdb_ltdb_unlock(ctdb_db, key);
680 ret = ctdb_client_force_migration(ctdb_db, key);
682 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
689 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
694 get a readonly lock on a record, and return the records data. Blocks until it gets the lock
696 struct ctdb_record_handle *
697 ctdb_fetch_readonly_lock(
698 struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
699 TDB_DATA key, TDB_DATA *data,
703 struct ctdb_record_handle *h;
704 struct ctdb_ltdb_header *roheader = NULL;
706 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
711 h->ctdb_db = ctdb_db;
713 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
714 if (h->key.dptr == NULL) {
725 talloc_free(roheader);
728 talloc_free(data->dptr);
732 /* Lock the record/chain */
733 ret = ctdb_ltdb_lock(ctdb_db, key);
735 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
740 talloc_set_destructor(h, fetch_lock_destructor);
742 /* Check if record exists yet in the TDB */
743 ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
745 ctdb_ltdb_unlock(ctdb_db, key);
746 ret = ctdb_client_force_migration(ctdb_db, key);
748 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
755 /* if this is a request for read/write and we have delegations
756 we have to revoke all delegations first
759 && (h->header.dmaster == ctdb_db->ctdb->pnn)
760 && (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
761 ctdb_ltdb_unlock(ctdb_db, key);
762 ret = ctdb_client_force_migration(ctdb_db, key);
764 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
771 /* if we are dmaster, just return the handle */
772 if (h->header.dmaster == ctdb_db->ctdb->pnn) {
776 if (read_only != 0) {
777 TDB_DATA rodata = {NULL, 0};
779 if ((h->header.flags & CTDB_REC_RO_HAVE_READONLY)
780 || (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
784 ctdb_ltdb_unlock(ctdb_db, key);
785 ret = ctdb_client_fetch_readonly(ctdb_db, key, h, &roheader, &rodata);
787 DEBUG(DEBUG_ERR,("ctdb_fetch_readonly_lock: failed. force migration and try again\n"));
788 ret = ctdb_client_force_migration(ctdb_db, key);
790 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
798 if (!(roheader->flags&CTDB_REC_RO_HAVE_READONLY)) {
799 ret = ctdb_client_force_migration(ctdb_db, key);
801 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
809 ret = ctdb_ltdb_lock(ctdb_db, key);
811 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
816 ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
818 ctdb_ltdb_unlock(ctdb_db, key);
820 ret = ctdb_client_force_migration(ctdb_db, key);
822 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
833 /* we are not dmaster and this was not a request for a readonly lock
834 * so unlock the record, migrate it and try again
836 ctdb_ltdb_unlock(ctdb_db, key);
837 ret = ctdb_client_force_migration(ctdb_db, key);
839 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
847 store some data to the record that was locked with ctdb_fetch_lock()
849 int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
851 if (h->ctdb_db->persistent) {
852 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
856 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
860 non-locking fetch of a record
862 int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
863 TDB_DATA key, TDB_DATA *data)
865 struct ctdb_call call;
868 call.call_id = CTDB_FETCH_FUNC;
869 call.call_data.dptr = NULL;
870 call.call_data.dsize = 0;
873 ret = ctdb_call(ctdb_db, &call);
876 *data = call.reply_data;
877 talloc_steal(mem_ctx, data->dptr);
886 called when a control completes or timesout to invoke the callback
887 function the user provided
889 static void invoke_control_callback(struct event_context *ev, struct timed_event *te,
890 struct timeval t, void *private_data)
892 struct ctdb_client_control_state *state;
893 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
896 state = talloc_get_type(private_data, struct ctdb_client_control_state);
897 talloc_steal(tmp_ctx, state);
899 ret = ctdb_control_recv(state->ctdb, state, state,
904 DEBUG(DEBUG_DEBUG,("ctdb_control_recv() failed, ignoring return code %d\n", ret));
907 talloc_free(tmp_ctx);
911 called when a CTDB_REPLY_CONTROL packet comes in in the client
913 This packet comes in response to a CTDB_REQ_CONTROL request packet. It
914 contains any reply data from the control
916 static void ctdb_client_reply_control(struct ctdb_context *ctdb,
917 struct ctdb_req_header *hdr)
919 struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
920 struct ctdb_client_control_state *state;
922 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_control_state);
924 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
928 if (hdr->reqid != state->reqid) {
929 /* we found a record but it was the wrong one */
930 DEBUG(DEBUG_ERR, ("Dropped orphaned reply control with reqid:%u\n",hdr->reqid));
934 state->outdata.dptr = c->data;
935 state->outdata.dsize = c->datalen;
936 state->status = c->status;
938 state->errormsg = talloc_strndup(state,
939 (char *)&c->data[c->datalen],
943 /* state->outdata now uses resources from c so we dont want c
944 to just dissappear from under us while state is still alive
946 talloc_steal(state, c);
948 state->state = CTDB_CONTROL_DONE;
950 /* if we had a callback registered for this control, pull the response
951 and call the callback.
953 if (state->async.fn) {
954 event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
960 destroy a ctdb_control in client
962 static int ctdb_client_control_destructor(struct ctdb_client_control_state *state)
964 ctdb_reqid_remove(state->ctdb, state->reqid);
969 /* time out handler for ctdb_control */
970 static void control_timeout_func(struct event_context *ev, struct timed_event *te,
971 struct timeval t, void *private_data)
973 struct ctdb_client_control_state *state = talloc_get_type(private_data, struct ctdb_client_control_state);
975 DEBUG(DEBUG_ERR,(__location__ " control timed out. reqid:%u opcode:%u "
976 "dstnode:%u\n", state->reqid, state->c->opcode,
977 state->c->hdr.destnode));
979 state->state = CTDB_CONTROL_TIMEOUT;
981 /* if we had a callback registered for this control, pull the response
982 and call the callback.
984 if (state->async.fn) {
985 event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
989 /* async version of send control request */
990 struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
991 uint32_t destnode, uint64_t srvid,
992 uint32_t opcode, uint32_t flags, TDB_DATA data,
994 struct timeval *timeout,
997 struct ctdb_client_control_state *state;
999 struct ctdb_req_control *c;
1006 /* if the domain socket is not yet open, open it */
1007 if (ctdb->daemon.sd==-1) {
1008 ctdb_socket_connect(ctdb);
1011 state = talloc_zero(mem_ctx, struct ctdb_client_control_state);
1012 CTDB_NO_MEMORY_NULL(ctdb, state);
1015 state->reqid = ctdb_reqid_new(ctdb, state);
1016 state->state = CTDB_CONTROL_WAIT;
1017 state->errormsg = NULL;
1019 talloc_set_destructor(state, ctdb_client_control_destructor);
1021 len = offsetof(struct ctdb_req_control, data) + data.dsize;
1022 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
1023 len, struct ctdb_req_control);
1025 CTDB_NO_MEMORY_NULL(ctdb, c);
1026 c->hdr.reqid = state->reqid;
1027 c->hdr.destnode = destnode;
1032 c->datalen = data.dsize;
1034 memcpy(&c->data[0], data.dptr, data.dsize);
1038 if (timeout && !timeval_is_zero(timeout)) {
1039 event_add_timed(ctdb->ev, state, *timeout, control_timeout_func, state);
1042 ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
1048 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
1057 /* async version of receive control reply */
1058 int ctdb_control_recv(struct ctdb_context *ctdb,
1059 struct ctdb_client_control_state *state,
1060 TALLOC_CTX *mem_ctx,
1061 TDB_DATA *outdata, int32_t *status, char **errormsg)
1063 TALLOC_CTX *tmp_ctx;
1065 if (status != NULL) {
1068 if (errormsg != NULL) {
1072 if (state == NULL) {
1076 /* prevent double free of state */
1077 tmp_ctx = talloc_new(ctdb);
1078 talloc_steal(tmp_ctx, state);
1080 /* loop one event at a time until we either timeout or the control
1083 while (state->state == CTDB_CONTROL_WAIT) {
1084 event_loop_once(ctdb->ev);
1087 if (state->state != CTDB_CONTROL_DONE) {
1088 DEBUG(DEBUG_ERR,(__location__ " ctdb_control_recv failed\n"));
1089 if (state->async.fn) {
1090 state->async.fn(state);
1092 talloc_free(tmp_ctx);
1096 if (state->errormsg) {
1097 DEBUG(DEBUG_ERR,("ctdb_control error: '%s'\n", state->errormsg));
1099 (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
1101 if (state->async.fn) {
1102 state->async.fn(state);
1104 talloc_free(tmp_ctx);
1109 *outdata = state->outdata;
1110 outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
1114 *status = state->status;
1117 if (state->async.fn) {
1118 state->async.fn(state);
1121 talloc_free(tmp_ctx);
1128 send a ctdb control message
1129 timeout specifies how long we should wait for a reply.
1130 if timeout is NULL we wait indefinitely
1132 int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
1133 uint32_t opcode, uint32_t flags, TDB_DATA data,
1134 TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
1135 struct timeval *timeout,
1138 struct ctdb_client_control_state *state;
1140 state = ctdb_control_send(ctdb, destnode, srvid, opcode,
1141 flags, data, mem_ctx,
1144 /* FIXME: Error conditions in ctdb_control_send return NULL without
1145 * setting errormsg. So, there is no way to distinguish between sucess
1146 * and failure when CTDB_CTRL_FLAG_NOREPLY is set */
1147 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
1148 if (status != NULL) {
1154 return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
1162 a process exists call. Returns 0 if process exists, -1 otherwise
1164 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
1170 data.dptr = (uint8_t*)&pid;
1171 data.dsize = sizeof(pid);
1173 ret = ctdb_control(ctdb, destnode, 0,
1174 CTDB_CONTROL_PROCESS_EXISTS, 0, data,
1175 NULL, NULL, &status, NULL, NULL);
1177 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
1185 get remote statistics
1187 int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
1193 ret = ctdb_control(ctdb, destnode, 0,
1194 CTDB_CONTROL_STATISTICS, 0, tdb_null,
1195 ctdb, &data, &res, NULL, NULL);
1196 if (ret != 0 || res != 0) {
1197 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
1201 if (data.dsize != sizeof(struct ctdb_statistics)) {
1202 DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
1203 (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
1207 *status = *(struct ctdb_statistics *)data.dptr;
1208 talloc_free(data.dptr);
1214 shutdown a remote ctdb node
1216 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1218 struct ctdb_client_control_state *state;
1220 state = ctdb_control_send(ctdb, destnode, 0,
1221 CTDB_CONTROL_SHUTDOWN, 0, tdb_null,
1222 NULL, &timeout, NULL);
1223 if (state == NULL) {
1224 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
1232 get vnn map from a remote node
1234 int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
1239 struct ctdb_vnn_map_wire *map;
1241 ret = ctdb_control(ctdb, destnode, 0,
1242 CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
1243 mem_ctx, &outdata, &res, &timeout, NULL);
1244 if (ret != 0 || res != 0) {
1245 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
1249 map = (struct ctdb_vnn_map_wire *)outdata.dptr;
1250 if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
1251 outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
1252 DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
1256 (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
1257 CTDB_NO_MEMORY(ctdb, *vnnmap);
1258 (*vnnmap)->generation = map->generation;
1259 (*vnnmap)->size = map->size;
1260 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
1262 CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
1263 memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
1264 talloc_free(outdata.dptr);
1271 get the recovery mode of a remote node
1273 struct ctdb_client_control_state *
1274 ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
1276 return ctdb_control_send(ctdb, destnode, 0,
1277 CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
1278 mem_ctx, &timeout, NULL);
1281 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
1286 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1288 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
1293 *recmode = (uint32_t)res;
1299 int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
1301 struct ctdb_client_control_state *state;
1303 state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
1304 return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
1311 set the recovery mode of a remote node
1313 int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
1319 data.dsize = sizeof(uint32_t);
1320 data.dptr = (unsigned char *)&recmode;
1322 ret = ctdb_control(ctdb, destnode, 0,
1323 CTDB_CONTROL_SET_RECMODE, 0, data,
1324 NULL, NULL, &res, &timeout, NULL);
1325 if (ret != 0 || res != 0) {
1326 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
1336 get the recovery master of a remote node
1338 struct ctdb_client_control_state *
1339 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
1340 struct timeval timeout, uint32_t destnode)
1342 return ctdb_control_send(ctdb, destnode, 0,
1343 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
1344 mem_ctx, &timeout, NULL);
1347 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
1352 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1354 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
1359 *recmaster = (uint32_t)res;
1365 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
1367 struct ctdb_client_control_state *state;
1369 state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
1370 return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
1375 set the recovery master of a remote node
1377 int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
1384 data.dsize = sizeof(uint32_t);
1385 data.dptr = (unsigned char *)&recmaster;
1387 ret = ctdb_control(ctdb, destnode, 0,
1388 CTDB_CONTROL_SET_RECMASTER, 0, data,
1389 NULL, NULL, &res, &timeout, NULL);
1390 if (ret != 0 || res != 0) {
1391 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
1400 get a list of databases off a remote node
1402 int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1403 TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
1409 ret = ctdb_control(ctdb, destnode, 0,
1410 CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
1411 mem_ctx, &outdata, &res, &timeout, NULL);
1412 if (ret != 0 || res != 0) {
1413 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
1417 *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1418 talloc_free(outdata.dptr);
1424 get a list of nodes (vnn and flags ) from a remote node
1426 int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
1427 struct timeval timeout, uint32_t destnode,
1428 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1434 ret = ctdb_control(ctdb, destnode, 0,
1435 CTDB_CONTROL_GET_NODEMAP, 0, tdb_null,
1436 mem_ctx, &outdata, &res, &timeout, NULL);
1437 if (ret == 0 && res == -1 && outdata.dsize == 0) {
1438 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
1439 return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
1441 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1442 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
1446 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1447 talloc_free(outdata.dptr);
1453 old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
1455 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb,
1456 struct timeval timeout, uint32_t destnode,
1457 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1461 struct ctdb_node_mapv4 *nodemapv4;
1464 ret = ctdb_control(ctdb, destnode, 0,
1465 CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null,
1466 mem_ctx, &outdata, &res, &timeout, NULL);
1467 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1468 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
1472 nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
1474 len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
1475 (*nodemap) = talloc_zero_size(mem_ctx, len);
1476 CTDB_NO_MEMORY(ctdb, (*nodemap));
1478 (*nodemap)->num = nodemapv4->num;
1479 for (i=0; i<nodemapv4->num; i++) {
1480 (*nodemap)->nodes[i].pnn = nodemapv4->nodes[i].pnn;
1481 (*nodemap)->nodes[i].flags = nodemapv4->nodes[i].flags;
1482 (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
1483 (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
1486 talloc_free(outdata.dptr);
1492 drop the transport, reload the nodes file and restart the transport
1494 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
1495 struct timeval timeout, uint32_t destnode)
1500 ret = ctdb_control(ctdb, destnode, 0,
1501 CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
1502 NULL, NULL, &res, &timeout, NULL);
1503 if (ret != 0 || res != 0) {
1504 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
1513 set vnn map on a node
1515 int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1516 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
1521 struct ctdb_vnn_map_wire *map;
1524 len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
1525 map = talloc_size(mem_ctx, len);
1526 CTDB_NO_MEMORY(ctdb, map);
1528 map->generation = vnnmap->generation;
1529 map->size = vnnmap->size;
1530 memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
1533 data.dptr = (uint8_t *)map;
1535 ret = ctdb_control(ctdb, destnode, 0,
1536 CTDB_CONTROL_SETVNNMAP, 0, data,
1537 NULL, NULL, &res, &timeout, NULL);
1538 if (ret != 0 || res != 0) {
1539 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
1550 async send for pull database
1552 struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
1553 struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
1554 uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
1557 struct ctdb_control_pulldb *pull;
1558 struct ctdb_client_control_state *state;
1560 pull = talloc(mem_ctx, struct ctdb_control_pulldb);
1561 CTDB_NO_MEMORY_NULL(ctdb, pull);
1564 pull->lmaster = lmaster;
1566 indata.dsize = sizeof(struct ctdb_control_pulldb);
1567 indata.dptr = (unsigned char *)pull;
1569 state = ctdb_control_send(ctdb, destnode, 0,
1570 CTDB_CONTROL_PULL_DB, 0, indata,
1571 mem_ctx, &timeout, NULL);
1578 async recv for pull database
1580 int ctdb_ctrl_pulldb_recv(
1581 struct ctdb_context *ctdb,
1582 TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state,
1588 ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
1589 if ( (ret != 0) || (res != 0) ){
1590 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
1598 pull all keys and records for a specific database on a node
1600 int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode,
1601 uint32_t dbid, uint32_t lmaster,
1602 TALLOC_CTX *mem_ctx, struct timeval timeout,
1605 struct ctdb_client_control_state *state;
1607 state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
1610 return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
1615 change dmaster for all keys in the database to the new value
1617 int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1618 TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
1624 indata.dsize = 2*sizeof(uint32_t);
1625 indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
1627 ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
1628 ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
1630 ret = ctdb_control(ctdb, destnode, 0,
1631 CTDB_CONTROL_SET_DMASTER, 0, indata,
1632 NULL, NULL, &res, &timeout, NULL);
1633 if (ret != 0 || res != 0) {
1634 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
1642 ping a node, return number of clients connected
1644 int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
1649 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0,
1650 tdb_null, NULL, NULL, &res, NULL, NULL);
1657 int ctdb_ctrl_get_runstate(struct ctdb_context *ctdb,
1658 struct timeval timeout,
1666 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_RUNSTATE, 0,
1667 tdb_null, ctdb, &outdata, &res, &timeout, NULL);
1668 if (ret != 0 || res != 0) {
1669 DEBUG(DEBUG_ERR,("ctdb_control for get_runstate failed\n"));
1670 return ret != 0 ? ret : res;
1673 if (outdata.dsize != sizeof(uint32_t)) {
1674 DEBUG(DEBUG_ERR,("Invalid return data in get_runstate\n"));
1675 talloc_free(outdata.dptr);
1679 if (runstate != NULL) {
1680 *runstate = *(uint32_t *)outdata.dptr;
1682 talloc_free(outdata.dptr);
1688 find the real path to a ltdb
1690 int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1697 data.dptr = (uint8_t *)&dbid;
1698 data.dsize = sizeof(dbid);
1700 ret = ctdb_control(ctdb, destnode, 0,
1701 CTDB_CONTROL_GETDBPATH, 0, data,
1702 mem_ctx, &data, &res, &timeout, NULL);
1703 if (ret != 0 || res != 0) {
1707 (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1708 if ((*path) == NULL) {
1712 talloc_free(data.dptr);
1718 find the name of a db
1720 int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1727 data.dptr = (uint8_t *)&dbid;
1728 data.dsize = sizeof(dbid);
1730 ret = ctdb_control(ctdb, destnode, 0,
1731 CTDB_CONTROL_GET_DBNAME, 0, data,
1732 mem_ctx, &data, &res, &timeout, NULL);
1733 if (ret != 0 || res != 0) {
1737 (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1738 if ((*name) == NULL) {
1742 talloc_free(data.dptr);
1748 get the health status of a db
1750 int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
1751 struct timeval timeout,
1753 uint32_t dbid, TALLOC_CTX *mem_ctx,
1754 const char **reason)
1760 data.dptr = (uint8_t *)&dbid;
1761 data.dsize = sizeof(dbid);
1763 ret = ctdb_control(ctdb, destnode, 0,
1764 CTDB_CONTROL_DB_GET_HEALTH, 0, data,
1765 mem_ctx, &data, &res, &timeout, NULL);
1766 if (ret != 0 || res != 0) {
1770 if (data.dsize == 0) {
1775 (*reason) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1776 if ((*reason) == NULL) {
1780 talloc_free(data.dptr);
1788 int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1789 TALLOC_CTX *mem_ctx, const char *name, bool persistent)
1795 data.dptr = discard_const(name);
1796 data.dsize = strlen(name)+1;
1798 ret = ctdb_control(ctdb, destnode, 0,
1799 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1801 mem_ctx, &data, &res, &timeout, NULL);
1803 if (ret != 0 || res != 0) {
1811 get debug level on a node
1813 int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
1819 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
1820 ctdb, &data, &res, NULL, NULL);
1821 if (ret != 0 || res != 0) {
1824 if (data.dsize != sizeof(int32_t)) {
1825 DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
1826 (unsigned)data.dsize));
1829 *level = *(int32_t *)data.dptr;
1830 talloc_free(data.dptr);
1835 set debug level on a node
1837 int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
1843 data.dptr = (uint8_t *)&level;
1844 data.dsize = sizeof(level);
1846 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data,
1847 NULL, NULL, &res, NULL, NULL);
1848 if (ret != 0 || res != 0) {
1856 get a list of connected nodes
1858 uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
1859 struct timeval timeout,
1860 TALLOC_CTX *mem_ctx,
1861 uint32_t *num_nodes)
1863 struct ctdb_node_map *map=NULL;
1869 ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
1874 nodes = talloc_array(mem_ctx, uint32_t, map->num);
1875 if (nodes == NULL) {
1879 for (i=0;i<map->num;i++) {
1880 if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
1881 nodes[*num_nodes] = map->nodes[i].pnn;
1893 int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
1898 ret = ctdb_control(ctdb, destnode, 0,
1899 CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null,
1900 NULL, NULL, &res, NULL, NULL);
1901 if (ret != 0 || res != 0) {
1902 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
1909 attach to a specific database - client call
1911 struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
1912 struct timeval timeout,
1917 struct ctdb_db_context *ctdb_db;
1922 ctdb_db = ctdb_db_handle(ctdb, name);
1927 ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
1928 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
1930 ctdb_db->ctdb = ctdb;
1931 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
1932 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
1934 data.dptr = discard_const(name);
1935 data.dsize = strlen(name)+1;
1937 /* tell ctdb daemon to attach */
1938 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags,
1939 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1940 0, data, ctdb_db, &data, &res, NULL, NULL);
1941 if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
1942 DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
1943 talloc_free(ctdb_db);
1947 ctdb_db->db_id = *(uint32_t *)data.dptr;
1948 talloc_free(data.dptr);
1950 ret = ctdb_ctrl_getdbpath(ctdb, timeout, CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
1952 DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
1953 talloc_free(ctdb_db);
1957 tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
1958 if (ctdb->valgrinding) {
1959 tdb_flags |= TDB_NOMMAP;
1961 tdb_flags |= TDB_DISALLOW_NESTING;
1963 ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
1964 if (ctdb_db->ltdb == NULL) {
1965 ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
1966 talloc_free(ctdb_db);
1970 ctdb_db->persistent = persistent;
1972 DLIST_ADD(ctdb->db_list, ctdb_db);
1974 /* add well known functions */
1975 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
1976 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
1977 ctdb_set_call(ctdb_db, ctdb_fetch_with_header_func, CTDB_FETCH_WITH_HEADER_FUNC);
1984 setup a call for a database
1986 int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
1988 struct ctdb_registered_call *call;
1993 struct ctdb_control_set_call c;
1996 /* this is no longer valid with the separate daemon architecture */
1997 c.db_id = ctdb_db->db_id;
2001 data.dptr = (uint8_t *)&c;
2002 data.dsize = sizeof(c);
2004 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_SET_CALL, 0,
2005 data, NULL, NULL, &status, NULL, NULL);
2006 if (ret != 0 || status != 0) {
2007 DEBUG(DEBUG_ERR,("ctdb_set_call failed for call %u\n", id));
2012 /* also register locally */
2013 call = talloc(ctdb_db, struct ctdb_registered_call);
2017 DLIST_ADD(ctdb_db->calls, call);
2022 struct traverse_state {
2025 ctdb_traverse_func fn;
2027 bool listemptyrecords;
2031 called on each key during a ctdb_traverse
2033 static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p)
2035 struct traverse_state *state = (struct traverse_state *)p;
2036 struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
2039 if (data.dsize < sizeof(uint32_t) ||
2040 d->length != data.dsize) {
2041 DEBUG(DEBUG_ERR,("Bad data size %u in traverse_handler\n", (unsigned)data.dsize));
2046 key.dsize = d->keylen;
2047 key.dptr = &d->data[0];
2048 data.dsize = d->datalen;
2049 data.dptr = &d->data[d->keylen];
2051 if (key.dsize == 0 && data.dsize == 0) {
2052 /* end of traverse */
2057 if (!state->listemptyrecords &&
2058 data.dsize == sizeof(struct ctdb_ltdb_header))
2060 /* empty records are deleted records in ctdb */
2064 if (state->fn(ctdb, key, data, state->private_data) != 0) {
2072 * start a cluster wide traverse, calling the supplied fn on each record
2073 * return the number of records traversed, or -1 on error
2075 * Extendet variant with a flag to signal whether empty records should
2078 static int ctdb_traverse_ext(struct ctdb_db_context *ctdb_db,
2079 ctdb_traverse_func fn,
2080 bool withemptyrecords,
2084 struct ctdb_traverse_start_ext t;
2087 uint64_t srvid = (getpid() | 0xFLL<<60);
2088 struct traverse_state state;
2092 state.private_data = private_data;
2094 state.listemptyrecords = withemptyrecords;
2096 ret = ctdb_client_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
2098 DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
2102 t.db_id = ctdb_db->db_id;
2105 t.withemptyrecords = withemptyrecords;
2107 data.dptr = (uint8_t *)&t;
2108 data.dsize = sizeof(t);
2110 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START_EXT, 0,
2111 data, NULL, NULL, &status, NULL, NULL);
2112 if (ret != 0 || status != 0) {
2113 DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
2114 ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2118 while (!state.done) {
2119 event_loop_once(ctdb_db->ctdb->ev);
2122 ret = ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2124 DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
2132 * start a cluster wide traverse, calling the supplied fn on each record
2133 * return the number of records traversed, or -1 on error
2135 * Standard version which does not list the empty records:
2136 * These are considered deleted.
2138 int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
2140 return ctdb_traverse_ext(ctdb_db, fn, false, private_data);
2143 #define ISASCII(x) (isprint(x) && !strchr("\"\\", (x)))
2145 called on each key during a catdb
2147 int ctdb_dumpdb_record(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p)
2150 struct ctdb_dump_db_context *c = (struct ctdb_dump_db_context *)p;
2152 struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
2154 fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
2155 for (i=0;i<key.dsize;i++) {
2156 if (ISASCII(key.dptr[i])) {
2157 fprintf(f, "%c", key.dptr[i]);
2159 fprintf(f, "\\%02X", key.dptr[i]);
2164 fprintf(f, "dmaster: %u\n", h->dmaster);
2165 fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
2167 if (c->printlmaster && ctdb->vnn_map != NULL) {
2168 fprintf(f, "lmaster: %u\n", ctdb_lmaster(ctdb, &key));
2172 fprintf(f, "hash: 0x%08x\n", ctdb_hash(&key));
2175 if (c->printrecordflags) {
2176 fprintf(f, "flags: 0x%08x", h->flags);
2177 if (h->flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA) printf(" MIGRATED_WITH_DATA");
2178 if (h->flags & CTDB_REC_FLAG_VACUUM_MIGRATED) printf(" VACUUM_MIGRATED");
2179 if (h->flags & CTDB_REC_FLAG_AUTOMATIC) printf(" AUTOMATIC");
2180 if (h->flags & CTDB_REC_RO_HAVE_DELEGATIONS) printf(" RO_HAVE_DELEGATIONS");
2181 if (h->flags & CTDB_REC_RO_HAVE_READONLY) printf(" RO_HAVE_READONLY");
2182 if (h->flags & CTDB_REC_RO_REVOKING_READONLY) printf(" RO_REVOKING_READONLY");
2183 if (h->flags & CTDB_REC_RO_REVOKE_COMPLETE) printf(" RO_REVOKE_COMPLETE");
2187 if (c->printdatasize) {
2188 fprintf(f, "data size: %u\n", (unsigned)data.dsize);
2190 fprintf(f, "data(%u) = \"", (unsigned)(data.dsize - sizeof(*h)));
2191 for (i=sizeof(*h);i<data.dsize;i++) {
2192 if (ISASCII(data.dptr[i])) {
2193 fprintf(f, "%c", data.dptr[i]);
2195 fprintf(f, "\\%02X", data.dptr[i]);
2207 convenience function to list all keys to stdout
2209 int ctdb_dump_db(struct ctdb_db_context *ctdb_db,
2210 struct ctdb_dump_db_context *ctx)
2212 return ctdb_traverse_ext(ctdb_db, ctdb_dumpdb_record,
2213 ctx->printemptyrecords, ctx);
2217 get the pid of a ctdb daemon
2219 int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
2224 ret = ctdb_control(ctdb, destnode, 0,
2225 CTDB_CONTROL_GET_PID, 0, tdb_null,
2226 NULL, NULL, &res, &timeout, NULL);
2228 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
2239 async freeze send control
2241 struct ctdb_client_control_state *
2242 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
2244 return ctdb_control_send(ctdb, destnode, priority,
2245 CTDB_CONTROL_FREEZE, 0, tdb_null,
2246 mem_ctx, &timeout, NULL);
2250 async freeze recv control
2252 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
2257 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
2258 if ( (ret != 0) || (res != 0) ){
2259 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
2267 freeze databases of a certain priority
2269 int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2271 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2272 struct ctdb_client_control_state *state;
2275 state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
2276 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
2277 talloc_free(tmp_ctx);
2282 /* Freeze all databases */
2283 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2287 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
2288 if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
2296 thaw databases of a certain priority
2298 int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2303 ret = ctdb_control(ctdb, destnode, priority,
2304 CTDB_CONTROL_THAW, 0, tdb_null,
2305 NULL, NULL, &res, &timeout, NULL);
2306 if (ret != 0 || res != 0) {
2307 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
2314 /* thaw all databases */
2315 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2317 return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
2321 get pnn of a node, or -1
2323 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2328 ret = ctdb_control(ctdb, destnode, 0,
2329 CTDB_CONTROL_GET_PNN, 0, tdb_null,
2330 NULL, NULL, &res, &timeout, NULL);
2332 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
2340 get the monitoring mode of a remote node
2342 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
2347 ret = ctdb_control(ctdb, destnode, 0,
2348 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
2349 NULL, NULL, &res, &timeout, NULL);
2351 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
2362 set the monitoring mode of a remote node to active
2364 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2369 ret = ctdb_control(ctdb, destnode, 0,
2370 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
2371 NULL, NULL,NULL, &timeout, NULL);
2373 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
2383 set the monitoring mode of a remote node to disable
2385 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2390 ret = ctdb_control(ctdb, destnode, 0,
2391 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
2392 NULL, NULL, NULL, &timeout, NULL);
2394 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
2406 sent to a node to make it take over an ip address
2408 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
2409 uint32_t destnode, struct ctdb_public_ip *ip)
2412 struct ctdb_public_ipv4 ipv4;
2416 if (ip->addr.sa.sa_family == AF_INET) {
2418 ipv4.sin = ip->addr.ip;
2420 data.dsize = sizeof(ipv4);
2421 data.dptr = (uint8_t *)&ipv4;
2423 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
2424 NULL, &res, &timeout, NULL);
2426 data.dsize = sizeof(*ip);
2427 data.dptr = (uint8_t *)ip;
2429 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
2430 NULL, &res, &timeout, NULL);
2433 if (ret != 0 || res != 0) {
2434 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
2443 sent to a node to make it release an ip address
2445 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
2446 uint32_t destnode, struct ctdb_public_ip *ip)
2449 struct ctdb_public_ipv4 ipv4;
2453 if (ip->addr.sa.sa_family == AF_INET) {
2455 ipv4.sin = ip->addr.ip;
2457 data.dsize = sizeof(ipv4);
2458 data.dptr = (uint8_t *)&ipv4;
2460 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
2461 NULL, &res, &timeout, NULL);
2463 data.dsize = sizeof(*ip);
2464 data.dptr = (uint8_t *)ip;
2466 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
2467 NULL, &res, &timeout, NULL);
2470 if (ret != 0 || res != 0) {
2471 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
2482 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
2483 struct timeval timeout,
2485 const char *name, uint32_t *value)
2487 struct ctdb_control_get_tunable *t;
2488 TDB_DATA data, outdata;
2492 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
2493 data.dptr = talloc_size(ctdb, data.dsize);
2494 CTDB_NO_MEMORY(ctdb, data.dptr);
2496 t = (struct ctdb_control_get_tunable *)data.dptr;
2497 t->length = strlen(name)+1;
2498 memcpy(t->name, name, t->length);
2500 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
2501 &outdata, &res, &timeout, NULL);
2502 talloc_free(data.dptr);
2503 if (ret != 0 || res != 0) {
2504 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
2505 return ret != 0 ? ret : res;
2508 if (outdata.dsize != sizeof(uint32_t)) {
2509 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
2510 talloc_free(outdata.dptr);
2514 *value = *(uint32_t *)outdata.dptr;
2515 talloc_free(outdata.dptr);
2523 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
2524 struct timeval timeout,
2526 const char *name, uint32_t value)
2528 struct ctdb_control_set_tunable *t;
2533 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
2534 data.dptr = talloc_size(ctdb, data.dsize);
2535 CTDB_NO_MEMORY(ctdb, data.dptr);
2537 t = (struct ctdb_control_set_tunable *)data.dptr;
2538 t->length = strlen(name)+1;
2539 memcpy(t->name, name, t->length);
2542 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
2543 NULL, &res, &timeout, NULL);
2544 talloc_free(data.dptr);
2545 if (ret != 0 || res != 0) {
2546 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
2556 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
2557 struct timeval timeout,
2559 TALLOC_CTX *mem_ctx,
2560 const char ***list, uint32_t *count)
2565 struct ctdb_control_list_tunable *t;
2568 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
2569 mem_ctx, &outdata, &res, &timeout, NULL);
2570 if (ret != 0 || res != 0) {
2571 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
2575 t = (struct ctdb_control_list_tunable *)outdata.dptr;
2576 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
2577 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
2578 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
2579 talloc_free(outdata.dptr);
2583 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
2584 CTDB_NO_MEMORY(ctdb, p);
2586 talloc_free(outdata.dptr);
2591 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
2592 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
2593 CTDB_NO_MEMORY(ctdb, *list);
2594 (*list)[*count] = talloc_strdup(*list, s);
2595 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
2605 int ctdb_ctrl_get_public_ips_flags(struct ctdb_context *ctdb,
2606 struct timeval timeout, uint32_t destnode,
2607 TALLOC_CTX *mem_ctx,
2609 struct ctdb_all_public_ips **ips)
2615 ret = ctdb_control(ctdb, destnode, 0,
2616 CTDB_CONTROL_GET_PUBLIC_IPS, flags, tdb_null,
2617 mem_ctx, &outdata, &res, &timeout, NULL);
2618 if (ret == 0 && res == -1) {
2619 DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
2620 return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
2622 if (ret != 0 || res != 0) {
2623 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
2627 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
2628 talloc_free(outdata.dptr);
2633 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
2634 struct timeval timeout, uint32_t destnode,
2635 TALLOC_CTX *mem_ctx,
2636 struct ctdb_all_public_ips **ips)
2638 return ctdb_ctrl_get_public_ips_flags(ctdb, timeout,
2643 int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
2644 struct timeval timeout, uint32_t destnode,
2645 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2650 struct ctdb_all_public_ipsv4 *ipsv4;
2652 ret = ctdb_control(ctdb, destnode, 0,
2653 CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null,
2654 mem_ctx, &outdata, &res, &timeout, NULL);
2655 if (ret != 0 || res != 0) {
2656 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
2660 ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
2661 len = offsetof(struct ctdb_all_public_ips, ips) +
2662 ipsv4->num*sizeof(struct ctdb_public_ip);
2663 *ips = talloc_zero_size(mem_ctx, len);
2664 CTDB_NO_MEMORY(ctdb, *ips);
2665 (*ips)->num = ipsv4->num;
2666 for (i=0; i<ipsv4->num; i++) {
2667 (*ips)->ips[i].pnn = ipsv4->ips[i].pnn;
2668 (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
2671 talloc_free(outdata.dptr);
2676 int ctdb_ctrl_get_public_ip_info(struct ctdb_context *ctdb,
2677 struct timeval timeout, uint32_t destnode,
2678 TALLOC_CTX *mem_ctx,
2679 const ctdb_sock_addr *addr,
2680 struct ctdb_control_public_ip_info **_info)
2686 struct ctdb_control_public_ip_info *info;
2690 indata.dptr = discard_const_p(uint8_t, addr);
2691 indata.dsize = sizeof(*addr);
2693 ret = ctdb_control(ctdb, destnode, 0,
2694 CTDB_CONTROL_GET_PUBLIC_IP_INFO, 0, indata,
2695 mem_ctx, &outdata, &res, &timeout, NULL);
2696 if (ret != 0 || res != 0) {
2697 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2698 "failed ret:%d res:%d\n",
2703 len = offsetof(struct ctdb_control_public_ip_info, ifaces);
2704 if (len > outdata.dsize) {
2705 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2706 "returned invalid data with size %u > %u\n",
2707 (unsigned int)outdata.dsize,
2708 (unsigned int)len));
2709 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2713 info = (struct ctdb_control_public_ip_info *)outdata.dptr;
2714 len += info->num*sizeof(struct ctdb_control_iface_info);
2716 if (len > outdata.dsize) {
2717 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2718 "returned invalid data with size %u > %u\n",
2719 (unsigned int)outdata.dsize,
2720 (unsigned int)len));
2721 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2725 /* make sure we null terminate the returned strings */
2726 for (i=0; i < info->num; i++) {
2727 info->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2730 *_info = (struct ctdb_control_public_ip_info *)talloc_memdup(mem_ctx,
2733 talloc_free(outdata.dptr);
2734 if (*_info == NULL) {
2735 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2736 "talloc_memdup size %u failed\n",
2737 (unsigned int)outdata.dsize));
2744 int ctdb_ctrl_get_ifaces(struct ctdb_context *ctdb,
2745 struct timeval timeout, uint32_t destnode,
2746 TALLOC_CTX *mem_ctx,
2747 struct ctdb_control_get_ifaces **_ifaces)
2752 struct ctdb_control_get_ifaces *ifaces;
2756 ret = ctdb_control(ctdb, destnode, 0,
2757 CTDB_CONTROL_GET_IFACES, 0, tdb_null,
2758 mem_ctx, &outdata, &res, &timeout, NULL);
2759 if (ret != 0 || res != 0) {
2760 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2761 "failed ret:%d res:%d\n",
2766 len = offsetof(struct ctdb_control_get_ifaces, ifaces);
2767 if (len > outdata.dsize) {
2768 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2769 "returned invalid data with size %u > %u\n",
2770 (unsigned int)outdata.dsize,
2771 (unsigned int)len));
2772 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2776 ifaces = (struct ctdb_control_get_ifaces *)outdata.dptr;
2777 len += ifaces->num*sizeof(struct ctdb_control_iface_info);
2779 if (len > outdata.dsize) {
2780 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2781 "returned invalid data with size %u > %u\n",
2782 (unsigned int)outdata.dsize,
2783 (unsigned int)len));
2784 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2788 /* make sure we null terminate the returned strings */
2789 for (i=0; i < ifaces->num; i++) {
2790 ifaces->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2793 *_ifaces = (struct ctdb_control_get_ifaces *)talloc_memdup(mem_ctx,
2796 talloc_free(outdata.dptr);
2797 if (*_ifaces == NULL) {
2798 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2799 "talloc_memdup size %u failed\n",
2800 (unsigned int)outdata.dsize));
2807 int ctdb_ctrl_set_iface_link(struct ctdb_context *ctdb,
2808 struct timeval timeout, uint32_t destnode,
2809 TALLOC_CTX *mem_ctx,
2810 const struct ctdb_control_iface_info *info)
2816 indata.dptr = discard_const_p(uint8_t, info);
2817 indata.dsize = sizeof(*info);
2819 ret = ctdb_control(ctdb, destnode, 0,
2820 CTDB_CONTROL_SET_IFACE_LINK_STATE, 0, indata,
2821 mem_ctx, NULL, &res, &timeout, NULL);
2822 if (ret != 0 || res != 0) {
2823 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set iface link "
2824 "failed ret:%d res:%d\n",
2833 set/clear the permanent disabled bit on a remote node
2835 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
2836 uint32_t set, uint32_t clear)
2840 struct ctdb_node_map *nodemap=NULL;
2841 struct ctdb_node_flag_change c;
2842 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2847 /* find the recovery master */
2848 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
2850 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
2851 talloc_free(tmp_ctx);
2856 /* read the node flags from the recmaster */
2857 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
2859 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
2860 talloc_free(tmp_ctx);
2863 if (destnode >= nodemap->num) {
2864 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
2865 talloc_free(tmp_ctx);
2870 c.old_flags = nodemap->nodes[destnode].flags;
2871 c.new_flags = c.old_flags;
2873 c.new_flags &= ~clear;
2875 data.dsize = sizeof(c);
2876 data.dptr = (unsigned char *)&c;
2878 /* send the flags update to all connected nodes */
2879 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
2881 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
2883 timeout, false, data,
2886 DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
2888 talloc_free(tmp_ctx);
2892 talloc_free(tmp_ctx);
2900 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
2901 struct timeval timeout,
2903 struct ctdb_tunable *tunables)
2909 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
2910 &outdata, &res, &timeout, NULL);
2911 if (ret != 0 || res != 0) {
2912 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
2916 if (outdata.dsize != sizeof(*tunables)) {
2917 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
2918 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
2922 *tunables = *(struct ctdb_tunable *)outdata.dptr;
2923 talloc_free(outdata.dptr);
2928 add a public address to a node
2930 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
2931 struct timeval timeout,
2933 struct ctdb_control_ip_iface *pub)
2939 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2940 data.dptr = (unsigned char *)pub;
2942 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
2943 NULL, &res, &timeout, NULL);
2944 if (ret != 0 || res != 0) {
2945 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
2953 delete a public address from a node
2955 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
2956 struct timeval timeout,
2958 struct ctdb_control_ip_iface *pub)
2964 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2965 data.dptr = (unsigned char *)pub;
2967 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
2968 NULL, &res, &timeout, NULL);
2969 if (ret != 0 || res != 0) {
2970 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
2978 kill a tcp connection
2980 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
2981 struct timeval timeout,
2983 struct ctdb_control_killtcp *killtcp)
2989 data.dsize = sizeof(struct ctdb_control_killtcp);
2990 data.dptr = (unsigned char *)killtcp;
2992 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
2993 NULL, &res, &timeout, NULL);
2994 if (ret != 0 || res != 0) {
2995 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
3005 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
3006 struct timeval timeout,
3008 ctdb_sock_addr *addr,
3014 struct ctdb_control_gratious_arp *gratious_arp;
3015 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3018 len = strlen(ifname)+1;
3019 gratious_arp = talloc_size(tmp_ctx,
3020 offsetof(struct ctdb_control_gratious_arp, iface) + len);
3021 CTDB_NO_MEMORY(ctdb, gratious_arp);
3023 gratious_arp->addr = *addr;
3024 gratious_arp->len = len;
3025 memcpy(&gratious_arp->iface[0], ifname, len);
3028 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
3029 data.dptr = (unsigned char *)gratious_arp;
3031 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
3032 NULL, &res, &timeout, NULL);
3033 if (ret != 0 || res != 0) {
3034 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
3035 talloc_free(tmp_ctx);
3039 talloc_free(tmp_ctx);
3044 get a list of all tcp tickles that a node knows about for a particular vnn
3046 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
3047 struct timeval timeout, uint32_t destnode,
3048 TALLOC_CTX *mem_ctx,
3049 ctdb_sock_addr *addr,
3050 struct ctdb_control_tcp_tickle_list **list)
3053 TDB_DATA data, outdata;
3056 data.dptr = (uint8_t*)addr;
3057 data.dsize = sizeof(ctdb_sock_addr);
3059 ret = ctdb_control(ctdb, destnode, 0,
3060 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
3061 mem_ctx, &outdata, &status, NULL, NULL);
3062 if (ret != 0 || status != 0) {
3063 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
3067 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
3073 register a server id
3075 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
3076 struct timeval timeout,
3077 struct ctdb_server_id *id)
3083 data.dsize = sizeof(struct ctdb_server_id);
3084 data.dptr = (unsigned char *)id;
3086 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3087 CTDB_CONTROL_REGISTER_SERVER_ID,
3089 NULL, &res, &timeout, NULL);
3090 if (ret != 0 || res != 0) {
3091 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
3099 unregister a server id
3101 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
3102 struct timeval timeout,
3103 struct ctdb_server_id *id)
3109 data.dsize = sizeof(struct ctdb_server_id);
3110 data.dptr = (unsigned char *)id;
3112 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3113 CTDB_CONTROL_UNREGISTER_SERVER_ID,
3115 NULL, &res, &timeout, NULL);
3116 if (ret != 0 || res != 0) {
3117 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
3126 check if a server id exists
3128 if a server id does exist, return *status == 1, otherwise *status == 0
3130 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
3131 struct timeval timeout,
3133 struct ctdb_server_id *id,
3140 data.dsize = sizeof(struct ctdb_server_id);
3141 data.dptr = (unsigned char *)id;
3143 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
3145 NULL, &res, &timeout, NULL);
3147 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
3161 get the list of server ids that are registered on a node
3163 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
3164 TALLOC_CTX *mem_ctx,
3165 struct timeval timeout, uint32_t destnode,
3166 struct ctdb_server_id_list **svid_list)
3172 ret = ctdb_control(ctdb, destnode, 0,
3173 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
3174 mem_ctx, &outdata, &res, &timeout, NULL);
3175 if (ret != 0 || res != 0) {
3176 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
3180 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
3186 initialise the ctdb daemon for client applications
3188 NOTE: In current code the daemon does not fork. This is for testing purposes only
3189 and to simplify the code.
3191 struct ctdb_context *ctdb_init(struct event_context *ev)
3194 struct ctdb_context *ctdb;
3196 ctdb = talloc_zero(ev, struct ctdb_context);
3198 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
3202 ctdb->idr = idr_init(ctdb);
3203 /* Wrap early to exercise code. */
3204 ctdb->lastid = INT_MAX-200;
3205 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
3207 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
3209 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
3214 ctdb->statistics.statistics_start_time = timeval_current();
3223 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
3225 ctdb->flags |= flags;
3229 setup the local socket name
3231 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
3233 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
3234 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
3239 const char *ctdb_get_socketname(struct ctdb_context *ctdb)
3241 return ctdb->daemon.name;
3245 return the pnn of this node
3247 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
3254 get the uptime of a remote node
3256 struct ctdb_client_control_state *
3257 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3259 return ctdb_control_send(ctdb, destnode, 0,
3260 CTDB_CONTROL_UPTIME, 0, tdb_null,
3261 mem_ctx, &timeout, NULL);
3264 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
3270 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3271 if (ret != 0 || res != 0) {
3272 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
3276 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
3281 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
3283 struct ctdb_client_control_state *state;
3285 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
3286 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
3290 send a control to execute the "recovered" event script on a node
3292 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3297 ret = ctdb_control(ctdb, destnode, 0,
3298 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
3299 NULL, NULL, &status, &timeout, NULL);
3300 if (ret != 0 || status != 0) {
3301 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
3309 callback for the async helpers used when sending the same control
3310 to multiple nodes in parallell.
3312 static void async_callback(struct ctdb_client_control_state *state)
3314 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
3315 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
3319 uint32_t destnode = state->c->hdr.destnode;
3321 /* one more node has responded with recmode data */
3324 /* if we failed to push the db, then return an error and let
3325 the main loop try again.
3327 if (state->state != CTDB_CONTROL_DONE) {
3328 if ( !data->dont_log_errors) {
3329 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
3332 if (state->state == CTDB_CONTROL_TIMEOUT) {
3337 if (data->fail_callback) {
3338 data->fail_callback(ctdb, destnode, res, outdata,
3339 data->callback_data);
3344 state->async.fn = NULL;
3346 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
3347 if ((ret != 0) || (res != 0)) {
3348 if ( !data->dont_log_errors) {
3349 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
3352 if (data->fail_callback) {
3353 data->fail_callback(ctdb, destnode, res, outdata,
3354 data->callback_data);
3357 if ((ret == 0) && (data->callback != NULL)) {
3358 data->callback(ctdb, destnode, res, outdata,
3359 data->callback_data);
3364 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
3366 /* set up the callback functions */
3367 state->async.fn = async_callback;
3368 state->async.private_data = data;
3370 /* one more control to wait for to complete */
3375 /* wait for up to the maximum number of seconds allowed
3376 or until all nodes we expect a response from has replied
3378 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
3380 while (data->count > 0) {
3381 event_loop_once(ctdb->ev);
3383 if (data->fail_count != 0) {
3384 if (!data->dont_log_errors) {
3385 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
3395 perform a simple control on the listed nodes
3396 The control cannot return data
3398 int ctdb_client_async_control(struct ctdb_context *ctdb,
3399 enum ctdb_controls opcode,
3402 struct timeval timeout,
3403 bool dont_log_errors,
3405 client_async_callback client_callback,
3406 client_async_callback fail_callback,
3407 void *callback_data)
3409 struct client_async_data *async_data;
3410 struct ctdb_client_control_state *state;
3413 async_data = talloc_zero(ctdb, struct client_async_data);
3414 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
3415 async_data->dont_log_errors = dont_log_errors;
3416 async_data->callback = client_callback;
3417 async_data->fail_callback = fail_callback;
3418 async_data->callback_data = callback_data;
3419 async_data->opcode = opcode;
3421 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
3423 /* loop over all nodes and send an async control to each of them */
3424 for (j=0; j<num_nodes; j++) {
3425 uint32_t pnn = nodes[j];
3427 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
3428 0, data, async_data, &timeout, NULL);
3429 if (state == NULL) {
3430 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
3431 talloc_free(async_data);
3435 ctdb_client_async_add(async_data, state);
3438 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
3439 talloc_free(async_data);
3443 talloc_free(async_data);
3447 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
3448 struct ctdb_vnn_map *vnn_map,
3449 TALLOC_CTX *mem_ctx,
3452 int i, j, num_nodes;
3455 for (i=num_nodes=0;i<vnn_map->size;i++) {
3456 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3462 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3463 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3465 for (i=j=0;i<vnn_map->size;i++) {
3466 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3469 nodes[j++] = vnn_map->map[i];
3475 /* Get list of nodes not including those with flags specified by mask.
3476 * If exclude_pnn is not -1 then exclude that pnn from the list.
3478 uint32_t *list_of_nodes(struct ctdb_context *ctdb,
3479 struct ctdb_node_map *node_map,
3480 TALLOC_CTX *mem_ctx,
3484 int i, j, num_nodes;
3487 for (i=num_nodes=0;i<node_map->num;i++) {
3488 if (node_map->nodes[i].flags & mask) {
3491 if (node_map->nodes[i].pnn == exclude_pnn) {
3497 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3498 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3500 for (i=j=0;i<node_map->num;i++) {
3501 if (node_map->nodes[i].flags & mask) {
3504 if (node_map->nodes[i].pnn == exclude_pnn) {
3507 nodes[j++] = node_map->nodes[i].pnn;
3513 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
3514 struct ctdb_node_map *node_map,
3515 TALLOC_CTX *mem_ctx,
3518 return list_of_nodes(ctdb, node_map, mem_ctx, NODE_FLAGS_INACTIVE,
3519 include_self ? -1 : ctdb->pnn);
3522 uint32_t *list_of_active_nodes_except_pnn(struct ctdb_context *ctdb,
3523 struct ctdb_node_map *node_map,
3524 TALLOC_CTX *mem_ctx,
3527 return list_of_nodes(ctdb, node_map, mem_ctx, NODE_FLAGS_INACTIVE, pnn);
3530 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
3531 struct ctdb_node_map *node_map,
3532 TALLOC_CTX *mem_ctx,
3535 return list_of_nodes(ctdb, node_map, mem_ctx, NODE_FLAGS_DISCONNECTED,
3536 include_self ? -1 : ctdb->pnn);
3540 this is used to test if a pnn lock exists and if it exists will return
3541 the number of connections that pnn has reported or -1 if that recovery
3542 daemon is not running.
3545 ctdb_read_pnn_lock(int fd, int32_t pnn)
3550 lock.l_type = F_WRLCK;
3551 lock.l_whence = SEEK_SET;
3556 if (fcntl(fd, F_GETLK, &lock) != 0) {
3557 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3561 if (lock.l_type == F_UNLCK) {
3565 if (pread(fd, &c, 1, pnn) == -1) {
3566 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3574 get capabilities of a remote node
3576 struct ctdb_client_control_state *
3577 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3579 return ctdb_control_send(ctdb, destnode, 0,
3580 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3581 mem_ctx, &timeout, NULL);
3584 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3590 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3591 if ( (ret != 0) || (res != 0) ) {
3592 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3597 *capabilities = *((uint32_t *)outdata.dptr);
3603 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3605 struct ctdb_client_control_state *state;
3606 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3609 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3610 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3611 talloc_free(tmp_ctx);
3616 * check whether a transaction is active on a given db on a given node
3618 int32_t ctdb_ctrl_transaction_active(struct ctdb_context *ctdb,
3626 indata.dptr = (uint8_t *)&db_id;
3627 indata.dsize = sizeof(db_id);
3629 ret = ctdb_control(ctdb, destnode, 0,
3630 CTDB_CONTROL_TRANS2_ACTIVE,
3631 0, indata, NULL, NULL, &status,
3635 DEBUG(DEBUG_ERR, (__location__ " ctdb control for transaction_active failed\n"));
3643 struct ctdb_transaction_handle {
3644 struct ctdb_db_context *ctdb_db;
3647 * we store the reads and writes done under a transaction:
3648 * - one list stores both reads and writes (m_all),
3649 * - the other just writes (m_write)
3651 struct ctdb_marshall_buffer *m_all;
3652 struct ctdb_marshall_buffer *m_write;
3655 /* start a transaction on a database */
3656 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
3658 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3662 /* start a transaction on a database */
3663 static int ctdb_transaction_fetch_start(struct ctdb_transaction_handle *h)
3665 struct ctdb_record_handle *rh;
3668 struct ctdb_ltdb_header header;
3669 TALLOC_CTX *tmp_ctx;
3670 const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
3672 struct ctdb_db_context *ctdb_db = h->ctdb_db;
3676 key.dptr = discard_const(keyname);
3677 key.dsize = strlen(keyname);
3679 if (!ctdb_db->persistent) {
3680 DEBUG(DEBUG_ERR,(__location__ " Attempted transaction on non-persistent database\n"));
3685 tmp_ctx = talloc_new(h);
3687 rh = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, NULL);
3689 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch_lock database\n"));
3690 talloc_free(tmp_ctx);
3694 status = ctdb_ctrl_transaction_active(ctdb_db->ctdb,
3698 unsigned long int usec = (1000 + random()) % 100000;
3699 DEBUG(DEBUG_DEBUG, (__location__ " transaction is active "
3700 "on db_id[0x%08x]. waiting for %lu "
3702 ctdb_db->db_id, usec));
3703 talloc_free(tmp_ctx);
3709 * store the pid in the database:
3710 * it is not enough that the node is dmaster...
3713 data.dptr = (unsigned char *)&pid;
3714 data.dsize = sizeof(pid_t);
3716 rh->header.dmaster = ctdb_db->ctdb->pnn;
3717 ret = ctdb_ltdb_store(ctdb_db, key, &(rh->header), data);
3719 DEBUG(DEBUG_ERR, (__location__ " Failed to store pid in "
3720 "transaction record\n"));
3721 talloc_free(tmp_ctx);
3727 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3729 DEBUG(DEBUG_ERR,(__location__ " Failed to start tdb transaction\n"));
3730 talloc_free(tmp_ctx);
3734 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, &data);
3736 DEBUG(DEBUG_ERR,(__location__ " Failed to re-fetch transaction "
3737 "lock record inside transaction\n"));
3738 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3739 talloc_free(tmp_ctx);
3743 if (header.dmaster != ctdb_db->ctdb->pnn) {
3744 DEBUG(DEBUG_DEBUG,(__location__ " not dmaster any more on "
3745 "transaction lock record\n"));
3746 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3747 talloc_free(tmp_ctx);
3751 if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
3752 DEBUG(DEBUG_DEBUG, (__location__ " my pid is not stored in "
3753 "the transaction lock record\n"));
3754 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3755 talloc_free(tmp_ctx);
3759 talloc_free(tmp_ctx);
3765 /* start a transaction on a database */
3766 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
3767 TALLOC_CTX *mem_ctx)
3769 struct ctdb_transaction_handle *h;
3772 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
3774 DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
3778 h->ctdb_db = ctdb_db;
3780 ret = ctdb_transaction_fetch_start(h);
3786 talloc_set_destructor(h, ctdb_transaction_destructor);
3794 fetch a record inside a transaction
3796 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
3797 TALLOC_CTX *mem_ctx,
3798 TDB_DATA key, TDB_DATA *data)
3800 struct ctdb_ltdb_header header;
3803 ZERO_STRUCT(header);
3805 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
3806 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3807 /* record doesn't exist yet */
3816 if (!h->in_replay) {
3817 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
3818 if (h->m_all == NULL) {
3819 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3828 stores a record inside a transaction
3830 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
3831 TDB_DATA key, TDB_DATA data)
3833 TALLOC_CTX *tmp_ctx = talloc_new(h);
3834 struct ctdb_ltdb_header header;
3838 ZERO_STRUCT(header);
3840 /* we need the header so we can update the RSN */
3841 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
3842 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3843 /* the record doesn't exist - create one with us as dmaster.
3844 This is only safe because we are in a transaction and this
3845 is a persistent database */
3846 ZERO_STRUCT(header);
3847 } else if (ret != 0) {
3848 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
3849 talloc_free(tmp_ctx);
3853 if (data.dsize == olddata.dsize &&
3854 memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
3855 /* save writing the same data */
3856 talloc_free(tmp_ctx);
3860 header.dmaster = h->ctdb_db->ctdb->pnn;
3863 if (!h->in_replay) {
3864 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
3865 if (h->m_all == NULL) {
3866 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3867 talloc_free(tmp_ctx);
3872 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
3873 if (h->m_write == NULL) {
3874 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3875 talloc_free(tmp_ctx);
3879 ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
3881 talloc_free(tmp_ctx);
3887 replay a transaction
3889 static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
3892 struct ctdb_rec_data *rec = NULL;
3894 h->in_replay = true;
3895 talloc_free(h->m_write);
3898 ret = ctdb_transaction_fetch_start(h);
3903 for (i=0;i<h->m_all->count;i++) {
3906 rec = ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
3908 DEBUG(DEBUG_ERR, (__location__ " Out of records in ctdb_replay_transaction?\n"));
3912 if (rec->reqid == 0) {
3914 if (ctdb_transaction_store(h, key, data) != 0) {
3919 TALLOC_CTX *tmp_ctx = talloc_new(h);
3921 if (ctdb_transaction_fetch(h, tmp_ctx, key, &data2) != 0) {
3922 talloc_free(tmp_ctx);
3925 if (data2.dsize != data.dsize ||
3926 memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
3927 /* the record has changed on us - we have to give up */
3928 talloc_free(tmp_ctx);
3931 talloc_free(tmp_ctx);
3938 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3944 commit a transaction
3946 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
3950 struct ctdb_context *ctdb = h->ctdb_db->ctdb;
3951 struct timeval timeout;
3952 enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
3954 talloc_set_destructor(h, NULL);
3956 /* our commit strategy is quite complex.
3958 - we first try to commit the changes to all other nodes
3960 - if that works, then we commit locally and we are done
3962 - if a commit on another node fails, then we need to cancel
3963 the transaction, then restart the transaction (thus
3964 opening a window of time for a pending recovery to
3965 complete), then replay the transaction, checking all the
3966 reads and writes (checking that reads give the same data,
3967 and writes succeed). Then we retry the transaction to the
3972 if (h->m_write == NULL) {
3973 /* no changes were made */
3974 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3979 /* tell ctdbd to commit to the other nodes */
3980 timeout = timeval_current_ofs(1, 0);
3981 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3982 retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY, 0,
3983 ctdb_marshall_finish(h->m_write), NULL, NULL, &status,
3985 if (ret != 0 || status != 0) {
3986 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3987 DEBUG(DEBUG_NOTICE, (__location__ " transaction commit%s failed"
3988 ", retrying after 1 second...\n",
3989 (retries==0)?"":"retry "));
3993 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3995 /* work out what error code we will give if we
3996 have to fail the operation */
3997 switch ((enum ctdb_trans2_commit_error)status) {
3998 case CTDB_TRANS2_COMMIT_SUCCESS:
3999 case CTDB_TRANS2_COMMIT_SOMEFAIL:
4000 case CTDB_TRANS2_COMMIT_TIMEOUT:
4001 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4003 case CTDB_TRANS2_COMMIT_ALLFAIL:
4004 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
4009 if (++retries == 100) {
4010 DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
4011 h->ctdb_db->db_id, retries, (unsigned)failure_control));
4012 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4013 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4014 tdb_null, NULL, NULL, NULL, NULL, NULL);
4019 if (ctdb_replay_transaction(h) != 0) {
4020 DEBUG(DEBUG_ERR, (__location__ " Failed to replay "
4021 "transaction on db 0x%08x, "
4022 "failure control =%u\n",
4024 (unsigned)failure_control));
4025 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4026 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4027 tdb_null, NULL, NULL, NULL, NULL, NULL);
4033 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4036 /* do the real commit locally */
4037 ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
4039 DEBUG(DEBUG_ERR, (__location__ " Failed to commit transaction "
4040 "on db id 0x%08x locally, "
4041 "failure_control=%u\n",
4043 (unsigned)failure_control));
4044 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4045 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4046 tdb_null, NULL, NULL, NULL, NULL, NULL);
4051 /* tell ctdbd that we are finished with our local commit */
4052 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4053 CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
4054 tdb_null, NULL, NULL, NULL, NULL, NULL);
4060 recovery daemon ping to main daemon
4062 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
4067 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
4068 ctdb, NULL, &res, NULL, NULL);
4069 if (ret != 0 || res != 0) {
4070 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
4077 /* When forking the main daemon and the child process needs to connect
4078 * back to the daemon as a client process, this function can be used
4079 * to change the ctdb context from daemon into client mode. The child
4080 * process must be created using ctdb_fork() and not fork() -
4081 * ctdb_fork() does some necessary housekeeping.
4083 int switch_from_server_to_client(struct ctdb_context *ctdb, const char *fmt, ...)
4088 /* Add extra information so we can identify this in the logs */
4090 debug_extra = talloc_strdup_append(talloc_vasprintf(NULL, fmt, ap), ":");
4093 /* get a new event context */
4094 ctdb->ev = event_context_init(ctdb);
4095 tevent_loop_allow_nesting(ctdb->ev);
4097 /* Connect to main CTDB daemon */
4098 ret = ctdb_socket_connect(ctdb);
4100 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
4104 ctdb->can_send_controls = true;
4110 get the status of running the monitor eventscripts: NULL means never run.
4112 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
4113 struct timeval timeout, uint32_t destnode,
4114 TALLOC_CTX *mem_ctx, enum ctdb_eventscript_call type,
4115 struct ctdb_scripts_wire **scripts)
4118 TDB_DATA outdata, indata;
4120 uint32_t uinttype = type;
4122 indata.dptr = (uint8_t *)&uinttype;
4123 indata.dsize = sizeof(uinttype);
4125 ret = ctdb_control(ctdb, destnode, 0,
4126 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, indata,
4127 mem_ctx, &outdata, &res, &timeout, NULL);
4128 if (ret != 0 || res != 0) {
4129 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
4133 if (outdata.dsize == 0) {
4136 *scripts = (struct ctdb_scripts_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4137 talloc_free(outdata.dptr);
4144 tell the main daemon how long it took to lock the reclock file
4146 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
4152 data.dptr = (uint8_t *)&latency;
4153 data.dsize = sizeof(latency);
4155 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
4156 ctdb, NULL, &res, NULL, NULL);
4157 if (ret != 0 || res != 0) {
4158 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
4166 get the name of the reclock file
4168 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
4169 uint32_t destnode, TALLOC_CTX *mem_ctx,
4176 ret = ctdb_control(ctdb, destnode, 0,
4177 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
4178 mem_ctx, &data, &res, &timeout, NULL);
4179 if (ret != 0 || res != 0) {
4183 if (data.dsize == 0) {
4186 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
4188 talloc_free(data.dptr);
4194 set the reclock filename for a node
4196 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
4202 if (reclock == NULL) {
4206 data.dsize = strlen(reclock) + 1;
4207 data.dptr = discard_const(reclock);
4210 ret = ctdb_control(ctdb, destnode, 0,
4211 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
4212 NULL, NULL, &res, &timeout, NULL);
4213 if (ret != 0 || res != 0) {
4214 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
4224 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4229 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
4230 ctdb, NULL, &res, &timeout, NULL);
4231 if (ret != 0 || res != 0) {
4232 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
4242 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4246 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
4247 ctdb, NULL, NULL, &timeout, NULL);
4249 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
4257 set the natgw state for a node
4259 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
4265 data.dsize = sizeof(natgwstate);
4266 data.dptr = (uint8_t *)&natgwstate;
4268 ret = ctdb_control(ctdb, destnode, 0,
4269 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
4270 NULL, NULL, &res, &timeout, NULL);
4271 if (ret != 0 || res != 0) {
4272 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
4280 set the lmaster role for a node
4282 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
4288 data.dsize = sizeof(lmasterrole);
4289 data.dptr = (uint8_t *)&lmasterrole;
4291 ret = ctdb_control(ctdb, destnode, 0,
4292 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
4293 NULL, NULL, &res, &timeout, NULL);
4294 if (ret != 0 || res != 0) {
4295 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
4303 set the recmaster role for a node
4305 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
4311 data.dsize = sizeof(recmasterrole);
4312 data.dptr = (uint8_t *)&recmasterrole;
4314 ret = ctdb_control(ctdb, destnode, 0,
4315 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
4316 NULL, NULL, &res, &timeout, NULL);
4317 if (ret != 0 || res != 0) {
4318 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
4325 /* enable an eventscript
4327 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4333 data.dsize = strlen(script) + 1;
4334 data.dptr = discard_const(script);
4336 ret = ctdb_control(ctdb, destnode, 0,
4337 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
4338 NULL, NULL, &res, &timeout, NULL);
4339 if (ret != 0 || res != 0) {
4340 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
4347 /* disable an eventscript
4349 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4355 data.dsize = strlen(script) + 1;
4356 data.dptr = discard_const(script);
4358 ret = ctdb_control(ctdb, destnode, 0,
4359 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
4360 NULL, NULL, &res, &timeout, NULL);
4361 if (ret != 0 || res != 0) {
4362 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
4370 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime)
4376 data.dsize = sizeof(*bantime);
4377 data.dptr = (uint8_t *)bantime;
4379 ret = ctdb_control(ctdb, destnode, 0,
4380 CTDB_CONTROL_SET_BAN_STATE, 0, data,
4381 NULL, NULL, &res, &timeout, NULL);
4382 if (ret != 0 || res != 0) {
4383 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4391 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime)
4396 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4398 ret = ctdb_control(ctdb, destnode, 0,
4399 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
4400 tmp_ctx, &outdata, &res, &timeout, NULL);
4401 if (ret != 0 || res != 0) {
4402 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4403 talloc_free(tmp_ctx);
4407 *bantime = (struct ctdb_ban_time *)talloc_steal(mem_ctx, outdata.dptr);
4408 talloc_free(tmp_ctx);
4414 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
4419 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4421 data.dptr = (uint8_t*)db_prio;
4422 data.dsize = sizeof(*db_prio);
4424 ret = ctdb_control(ctdb, destnode, 0,
4425 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
4426 tmp_ctx, NULL, &res, &timeout, NULL);
4427 if (ret != 0 || res != 0) {
4428 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4429 talloc_free(tmp_ctx);
4433 talloc_free(tmp_ctx);
4438 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
4443 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4445 data.dptr = (uint8_t*)&db_id;
4446 data.dsize = sizeof(db_id);
4448 ret = ctdb_control(ctdb, destnode, 0,
4449 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
4450 tmp_ctx, NULL, &res, &timeout, NULL);
4451 if (ret != 0 || res < 0) {
4452 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_db_priority failed\n"));
4453 talloc_free(tmp_ctx);
4461 talloc_free(tmp_ctx);
4466 int ctdb_ctrl_getstathistory(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_statistics_wire **stats)
4472 ret = ctdb_control(ctdb, destnode, 0,
4473 CTDB_CONTROL_GET_STAT_HISTORY, 0, tdb_null,
4474 mem_ctx, &outdata, &res, &timeout, NULL);
4475 if (ret != 0 || res != 0 || outdata.dsize == 0) {
4476 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getstathistory failed ret:%d res:%d\n", ret, res));
4480 *stats = (struct ctdb_statistics_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4481 talloc_free(outdata.dptr);
4486 struct ctdb_ltdb_header *ctdb_header_from_record_handle(struct ctdb_record_handle *h)
4496 struct ctdb_client_control_state *
4497 ctdb_ctrl_updaterecord_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_db_context *ctdb_db, TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA data)
4499 struct ctdb_client_control_state *handle;
4500 struct ctdb_marshall_buffer *m;
4501 struct ctdb_rec_data *rec;
4504 m = talloc_zero(mem_ctx, struct ctdb_marshall_buffer);
4506 DEBUG(DEBUG_ERR, ("Failed to allocate marshall buffer for update record\n"));
4510 m->db_id = ctdb_db->db_id;
4512 rec = ctdb_marshall_record(m, 0, key, header, data);
4514 DEBUG(DEBUG_ERR,("Failed to marshall record for update record\n"));
4518 m = talloc_realloc_size(mem_ctx, m, rec->length + offsetof(struct ctdb_marshall_buffer, data));
4520 DEBUG(DEBUG_CRIT,(__location__ " Failed to expand recdata\n"));
4525 memcpy((uint8_t *)m + offsetof(struct ctdb_marshall_buffer, data), rec, rec->length);
4528 outdata.dptr = (uint8_t *)m;
4529 outdata.dsize = talloc_get_size(m);
4531 handle = ctdb_control_send(ctdb, destnode, 0,
4532 CTDB_CONTROL_UPDATE_RECORD, 0, outdata,
4533 mem_ctx, &timeout, NULL);
4538 int ctdb_ctrl_updaterecord_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4543 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
4544 if ( (ret != 0) || (res != 0) ){
4545 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_update_record_recv failed\n"));
4553 ctdb_ctrl_updaterecord(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_db_context *ctdb_db, TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA data)
4555 struct ctdb_client_control_state *state;
4557 state = ctdb_ctrl_updaterecord_send(ctdb, mem_ctx, timeout, destnode, ctdb_db, key, header, data);
4558 return ctdb_ctrl_updaterecord_recv(ctdb, state);
4567 set a database to be readonly
4569 struct ctdb_client_control_state *
4570 ctdb_ctrl_set_db_readonly_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4574 data.dptr = (uint8_t *)&dbid;
4575 data.dsize = sizeof(dbid);
4577 return ctdb_control_send(ctdb, destnode, 0,
4578 CTDB_CONTROL_SET_DB_READONLY, 0, data,
4582 int ctdb_ctrl_set_db_readonly_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4587 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4588 if (ret != 0 || res != 0) {
4589 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_readonly_recv failed ret:%d res:%d\n", ret, res));
4596 int ctdb_ctrl_set_db_readonly(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4598 struct ctdb_client_control_state *state;
4600 state = ctdb_ctrl_set_db_readonly_send(ctdb, destnode, dbid);
4601 return ctdb_ctrl_set_db_readonly_recv(ctdb, state);
4605 set a database to be sticky
4607 struct ctdb_client_control_state *
4608 ctdb_ctrl_set_db_sticky_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4612 data.dptr = (uint8_t *)&dbid;
4613 data.dsize = sizeof(dbid);
4615 return ctdb_control_send(ctdb, destnode, 0,
4616 CTDB_CONTROL_SET_DB_STICKY, 0, data,
4620 int ctdb_ctrl_set_db_sticky_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4625 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4626 if (ret != 0 || res != 0) {
4627 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_sticky_recv failed ret:%d res:%d\n", ret, res));
4634 int ctdb_ctrl_set_db_sticky(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4636 struct ctdb_client_control_state *state;
4638 state = ctdb_ctrl_set_db_sticky_send(ctdb, destnode, dbid);
4639 return ctdb_ctrl_set_db_sticky_recv(ctdb, state);