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/>.
23 #include "lib/tdb/include/tdb.h"
24 #include "lib/util/dlinklist.h"
25 #include "lib/events/events.h"
26 #include "system/network.h"
27 #include "system/filesys.h"
28 #include "system/locale.h"
30 #include "../include/ctdb_private.h"
31 #include "lib/util/dlinklist.h"
34 allocate a packet for use in client<->daemon communication
36 struct ctdb_req_header *_ctdbd_allocate_pkt(struct ctdb_context *ctdb,
38 enum ctdb_operation operation,
39 size_t length, size_t slength,
43 struct ctdb_req_header *hdr;
45 length = MAX(length, slength);
46 size = (length+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
48 hdr = (struct ctdb_req_header *)talloc_size(mem_ctx, size);
50 DEBUG(DEBUG_ERR,("Unable to allocate packet for operation %u of length %u\n",
51 operation, (unsigned)length));
54 talloc_set_name_const(hdr, type);
55 memset(hdr, 0, slength);
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, 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);
91 for (fn=ctdb_db->calls;fn;fn=fn->next) {
92 if (fn->id == call->call_id) break;
95 ctdb_set_error(ctdb, "Unknown call id %u\n", call->call_id);
100 if (fn->fn(c) != 0) {
101 ctdb_set_error(ctdb, "ctdb_call %u failed\n", call->call_id);
106 if (header->laccessor != caller) {
109 header->laccessor = caller;
112 /* we need to force the record to be written out if this was a remote access,
113 so that the lacount is updated */
114 if (c->new_data == NULL && header->laccessor != ctdb->pnn) {
115 c->new_data = &c->record_data;
119 /* XXX check that we always have the lock here? */
120 if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
121 ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
128 call->reply_data = *c->reply_data;
130 talloc_steal(call, call->reply_data.dptr);
131 talloc_set_name_const(call->reply_data.dptr, __location__);
133 call->reply_data.dptr = NULL;
134 call->reply_data.dsize = 0;
136 call->status = c->status;
145 queue a packet for sending from client to daemon
147 static int ctdb_client_queue_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
149 return ctdb_queue_send(ctdb->daemon.queue, (uint8_t *)hdr, hdr->length);
154 called when a CTDB_REPLY_CALL packet comes in in the client
156 This packet comes in response to a CTDB_REQ_CALL request packet. It
157 contains any reply data from the call
159 static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
161 struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
162 struct ctdb_client_call_state *state;
164 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_call_state);
166 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
170 if (hdr->reqid != state->reqid) {
171 /* we found a record but it was the wrong one */
172 DEBUG(DEBUG_ERR, ("Dropped client call reply with reqid:%u\n",hdr->reqid));
176 state->call->reply_data.dptr = c->data;
177 state->call->reply_data.dsize = c->datalen;
178 state->call->status = c->status;
180 talloc_steal(state, c);
182 state->state = CTDB_CALL_DONE;
184 if (state->async.fn) {
185 state->async.fn(state);
189 static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
192 this is called in the client, when data comes in from the daemon
194 static void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
196 struct ctdb_context *ctdb = talloc_get_type(args, struct ctdb_context);
197 struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
200 /* place the packet as a child of a tmp_ctx. We then use
201 talloc_free() below to free it. If any of the calls want
202 to keep it, then they will steal it somewhere else, and the
203 talloc_free() will be a no-op */
204 tmp_ctx = talloc_new(ctdb);
205 talloc_steal(tmp_ctx, hdr);
208 DEBUG(DEBUG_INFO,("Daemon has exited - shutting down client\n"));
212 if (cnt < sizeof(*hdr)) {
213 DEBUG(DEBUG_CRIT,("Bad packet length %u in client\n", (unsigned)cnt));
216 if (cnt != hdr->length) {
217 ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
218 (unsigned)hdr->length, (unsigned)cnt);
222 if (hdr->ctdb_magic != CTDB_MAGIC) {
223 ctdb_set_error(ctdb, "Non CTDB packet rejected in client\n");
227 if (hdr->ctdb_version != CTDB_VERSION) {
228 ctdb_set_error(ctdb, "Bad CTDB version 0x%x rejected in client\n", hdr->ctdb_version);
232 switch (hdr->operation) {
233 case CTDB_REPLY_CALL:
234 ctdb_client_reply_call(ctdb, hdr);
237 case CTDB_REQ_MESSAGE:
238 ctdb_request_message(ctdb, hdr);
241 case CTDB_REPLY_CONTROL:
242 ctdb_client_reply_control(ctdb, hdr);
246 DEBUG(DEBUG_CRIT,("bogus operation code:%u\n",hdr->operation));
250 talloc_free(tmp_ctx);
254 connect to a unix domain socket
256 int ctdb_socket_connect(struct ctdb_context *ctdb)
258 struct sockaddr_un addr;
260 memset(&addr, 0, sizeof(addr));
261 addr.sun_family = AF_UNIX;
262 strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path));
264 ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
265 if (ctdb->daemon.sd == -1) {
266 DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
270 set_nonblocking(ctdb->daemon.sd);
271 set_close_on_exec(ctdb->daemon.sd);
273 if (connect(ctdb->daemon.sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
274 close(ctdb->daemon.sd);
275 ctdb->daemon.sd = -1;
276 DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
280 ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
282 ctdb_client_read_cb, ctdb);
287 struct ctdb_record_handle {
288 struct ctdb_db_context *ctdb_db;
291 struct ctdb_ltdb_header header;
296 make a recv call to the local ctdb daemon - called from client context
298 This is called when the program wants to wait for a ctdb_call to complete and get the
299 results. This call will block unless the call has already completed.
301 int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
307 while (state->state < CTDB_CALL_DONE) {
308 event_loop_once(state->ctdb_db->ctdb->ev);
310 if (state->state != CTDB_CALL_DONE) {
311 DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
316 if (state->call->reply_data.dsize) {
317 call->reply_data.dptr = talloc_memdup(state->ctdb_db,
318 state->call->reply_data.dptr,
319 state->call->reply_data.dsize);
320 call->reply_data.dsize = state->call->reply_data.dsize;
322 call->reply_data.dptr = NULL;
323 call->reply_data.dsize = 0;
325 call->status = state->call->status;
335 destroy a ctdb_call in client
337 static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
339 ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
344 construct an event driven local ctdb_call
346 this is used so that locally processed ctdb_call requests are processed
347 in an event driven manner
349 static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
350 struct ctdb_call *call,
351 struct ctdb_ltdb_header *header,
354 struct ctdb_client_call_state *state;
355 struct ctdb_context *ctdb = ctdb_db->ctdb;
358 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
359 CTDB_NO_MEMORY_NULL(ctdb, state);
360 state->call = talloc_zero(state, struct ctdb_call);
361 CTDB_NO_MEMORY_NULL(ctdb, state->call);
363 talloc_steal(state, data->dptr);
365 state->state = CTDB_CALL_DONE;
366 *(state->call) = *call;
367 state->ctdb_db = ctdb_db;
369 ret = ctdb_call_local(ctdb_db, state->call, header, state, data, ctdb->pnn);
375 make a ctdb call to the local daemon - async send. Called from client context.
377 This constructs a ctdb_call request and queues it for processing.
378 This call never blocks.
380 struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
381 struct ctdb_call *call)
383 struct ctdb_client_call_state *state;
384 struct ctdb_context *ctdb = ctdb_db->ctdb;
385 struct ctdb_ltdb_header header;
389 struct ctdb_req_call *c;
391 /* if the domain socket is not yet open, open it */
392 if (ctdb->daemon.sd==-1) {
393 ctdb_socket_connect(ctdb);
396 ret = ctdb_ltdb_lock(ctdb_db, call->key);
398 DEBUG(DEBUG_ERR,(__location__ " Failed to get chainlock\n"));
402 ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
404 if (ret == 0 && header.dmaster == ctdb->pnn) {
405 state = ctdb_client_call_local_send(ctdb_db, call, &header, &data);
406 talloc_free(data.dptr);
407 ctdb_ltdb_unlock(ctdb_db, call->key);
411 ctdb_ltdb_unlock(ctdb_db, call->key);
412 talloc_free(data.dptr);
414 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
416 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state\n"));
419 state->call = talloc_zero(state, struct ctdb_call);
420 if (state->call == NULL) {
421 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state->call\n"));
425 len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
426 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CALL, len, struct ctdb_req_call);
428 DEBUG(DEBUG_ERR, (__location__ " failed to allocate packet\n"));
432 state->reqid = ctdb_reqid_new(ctdb, state);
433 state->ctdb_db = ctdb_db;
434 talloc_set_destructor(state, ctdb_client_call_destructor);
436 c->hdr.reqid = state->reqid;
437 c->flags = call->flags;
438 c->db_id = ctdb_db->db_id;
439 c->callid = call->call_id;
441 c->keylen = call->key.dsize;
442 c->calldatalen = call->call_data.dsize;
443 memcpy(&c->data[0], call->key.dptr, call->key.dsize);
444 memcpy(&c->data[call->key.dsize],
445 call->call_data.dptr, call->call_data.dsize);
446 *(state->call) = *call;
447 state->call->call_data.dptr = &c->data[call->key.dsize];
448 state->call->key.dptr = &c->data[0];
450 state->state = CTDB_CALL_WAIT;
453 ctdb_client_queue_pkt(ctdb, &c->hdr);
460 full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
462 int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
464 struct ctdb_client_call_state *state;
466 state = ctdb_call_send(ctdb_db, call);
467 return ctdb_call_recv(state, call);
472 tell the daemon what messaging srvid we will use, and register the message
473 handler function in the client
475 int ctdb_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid,
476 ctdb_message_fn_t handler,
483 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_REGISTER_SRVID, 0,
484 tdb_null, NULL, NULL, &status, NULL, NULL);
485 if (res != 0 || status != 0) {
486 DEBUG(DEBUG_ERR,("Failed to register srvid %llu\n", (unsigned long long)srvid));
490 /* also need to register the handler with our own ctdb structure */
491 return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
495 tell the daemon we no longer want a srvid
497 int ctdb_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid, void *private_data)
502 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_DEREGISTER_SRVID, 0,
503 tdb_null, NULL, NULL, &status, NULL, NULL);
504 if (res != 0 || status != 0) {
505 DEBUG(DEBUG_ERR,("Failed to deregister srvid %llu\n", (unsigned long long)srvid));
509 /* also need to register the handler with our own ctdb structure */
510 ctdb_deregister_message_handler(ctdb, srvid, private_data);
516 send a message - from client context
518 int ctdb_send_message(struct ctdb_context *ctdb, uint32_t pnn,
519 uint64_t srvid, TDB_DATA data)
521 struct ctdb_req_message *r;
524 len = offsetof(struct ctdb_req_message, data) + data.dsize;
525 r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
526 len, struct ctdb_req_message);
527 CTDB_NO_MEMORY(ctdb, r);
529 r->hdr.destnode = pnn;
531 r->datalen = data.dsize;
532 memcpy(&r->data[0], data.dptr, data.dsize);
534 res = ctdb_client_queue_pkt(ctdb, &r->hdr);
545 cancel a ctdb_fetch_lock operation, releasing the lock
547 static int fetch_lock_destructor(struct ctdb_record_handle *h)
549 ctdb_ltdb_unlock(h->ctdb_db, h->key);
554 force the migration of a record to this node
556 static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
558 struct ctdb_call call;
560 call.call_id = CTDB_NULL_FUNC;
562 call.flags = CTDB_IMMEDIATE_MIGRATION;
563 return ctdb_call(ctdb_db, &call);
567 get a lock on a record, and return the records data. Blocks until it gets the lock
569 struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
570 TDB_DATA key, TDB_DATA *data)
573 struct ctdb_record_handle *h;
576 procedure is as follows:
578 1) get the chain lock.
579 2) check if we are dmaster
580 3) if we are the dmaster then return handle
581 4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
583 5) when we get the reply, goto (1)
586 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
591 h->ctdb_db = ctdb_db;
593 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
594 if (h->key.dptr == NULL) {
600 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize,
601 (const char *)key.dptr));
604 /* step 1 - get the chain lock */
605 ret = ctdb_ltdb_lock(ctdb_db, key);
607 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
612 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
614 talloc_set_destructor(h, fetch_lock_destructor);
616 ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
618 /* when torturing, ensure we test the remote path */
619 if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
621 h->header.dmaster = (uint32_t)-1;
625 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
627 if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
628 ctdb_ltdb_unlock(ctdb_db, key);
629 ret = ctdb_client_force_migration(ctdb_db, key);
631 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
638 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
643 store some data to the record that was locked with ctdb_fetch_lock()
645 int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
647 if (h->ctdb_db->persistent) {
648 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
652 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
656 non-locking fetch of a record
658 int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
659 TDB_DATA key, TDB_DATA *data)
661 struct ctdb_call call;
664 call.call_id = CTDB_FETCH_FUNC;
665 call.call_data.dptr = NULL;
666 call.call_data.dsize = 0;
668 ret = ctdb_call(ctdb_db, &call);
671 *data = call.reply_data;
672 talloc_steal(mem_ctx, data->dptr);
681 called when a control completes or timesout to invoke the callback
682 function the user provided
684 static void invoke_control_callback(struct event_context *ev, struct timed_event *te,
685 struct timeval t, void *private_data)
687 struct ctdb_client_control_state *state;
688 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
691 state = talloc_get_type(private_data, struct ctdb_client_control_state);
692 talloc_steal(tmp_ctx, state);
694 ret = ctdb_control_recv(state->ctdb, state, state,
699 talloc_free(tmp_ctx);
703 called when a CTDB_REPLY_CONTROL packet comes in in the client
705 This packet comes in response to a CTDB_REQ_CONTROL request packet. It
706 contains any reply data from the control
708 static void ctdb_client_reply_control(struct ctdb_context *ctdb,
709 struct ctdb_req_header *hdr)
711 struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
712 struct ctdb_client_control_state *state;
714 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_control_state);
716 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
720 if (hdr->reqid != state->reqid) {
721 /* we found a record but it was the wrong one */
722 DEBUG(DEBUG_ERR, ("Dropped orphaned reply control with reqid:%u\n",hdr->reqid));
726 state->outdata.dptr = c->data;
727 state->outdata.dsize = c->datalen;
728 state->status = c->status;
730 state->errormsg = talloc_strndup(state,
731 (char *)&c->data[c->datalen],
735 /* state->outdata now uses resources from c so we dont want c
736 to just dissappear from under us while state is still alive
738 talloc_steal(state, c);
740 state->state = CTDB_CONTROL_DONE;
742 /* if we had a callback registered for this control, pull the response
743 and call the callback.
745 if (state->async.fn) {
746 event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
752 destroy a ctdb_control in client
754 static int ctdb_control_destructor(struct ctdb_client_control_state *state)
756 ctdb_reqid_remove(state->ctdb, state->reqid);
761 /* time out handler for ctdb_control */
762 static void control_timeout_func(struct event_context *ev, struct timed_event *te,
763 struct timeval t, void *private_data)
765 struct ctdb_client_control_state *state = talloc_get_type(private_data, struct ctdb_client_control_state);
767 DEBUG(DEBUG_ERR,("control timed out. reqid:%d opcode:%d dstnode:%d\n", state->reqid, state->c->opcode, state->c->hdr.destnode));
769 state->state = CTDB_CONTROL_TIMEOUT;
771 /* if we had a callback registered for this control, pull the response
772 and call the callback.
774 if (state->async.fn) {
775 event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
779 /* async version of send control request */
780 struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
781 uint32_t destnode, uint64_t srvid,
782 uint32_t opcode, uint32_t flags, TDB_DATA data,
784 struct timeval *timeout,
787 struct ctdb_client_control_state *state;
789 struct ctdb_req_control *c;
796 /* if the domain socket is not yet open, open it */
797 if (ctdb->daemon.sd==-1) {
798 ctdb_socket_connect(ctdb);
801 state = talloc_zero(mem_ctx, struct ctdb_client_control_state);
802 CTDB_NO_MEMORY_NULL(ctdb, state);
805 state->reqid = ctdb_reqid_new(ctdb, state);
806 state->state = CTDB_CONTROL_WAIT;
807 state->errormsg = NULL;
809 talloc_set_destructor(state, ctdb_control_destructor);
811 len = offsetof(struct ctdb_req_control, data) + data.dsize;
812 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
813 len, struct ctdb_req_control);
815 CTDB_NO_MEMORY_NULL(ctdb, c);
816 c->hdr.reqid = state->reqid;
817 c->hdr.destnode = destnode;
822 c->datalen = data.dsize;
824 memcpy(&c->data[0], data.dptr, data.dsize);
828 if (timeout && !timeval_is_zero(timeout)) {
829 event_add_timed(ctdb->ev, state, *timeout, control_timeout_func, state);
832 ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
838 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
847 /* async version of receive control reply */
848 int ctdb_control_recv(struct ctdb_context *ctdb,
849 struct ctdb_client_control_state *state,
851 TDB_DATA *outdata, int32_t *status, char **errormsg)
855 if (status != NULL) {
858 if (errormsg != NULL) {
866 /* prevent double free of state */
867 tmp_ctx = talloc_new(ctdb);
868 talloc_steal(tmp_ctx, state);
870 /* loop one event at a time until we either timeout or the control
873 while (state->state == CTDB_CONTROL_WAIT) {
874 event_loop_once(ctdb->ev);
877 if (state->state != CTDB_CONTROL_DONE) {
878 DEBUG(DEBUG_ERR,(__location__ " ctdb_control_recv failed\n"));
879 if (state->async.fn) {
880 state->async.fn(state);
882 talloc_free(tmp_ctx);
886 if (state->errormsg) {
887 DEBUG(DEBUG_ERR,("ctdb_control error: '%s'\n", state->errormsg));
889 (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
891 if (state->async.fn) {
892 state->async.fn(state);
894 talloc_free(tmp_ctx);
899 *outdata = state->outdata;
900 outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
904 *status = state->status;
907 if (state->async.fn) {
908 state->async.fn(state);
911 talloc_free(tmp_ctx);
918 send a ctdb control message
919 timeout specifies how long we should wait for a reply.
920 if timeout is NULL we wait indefinitely
922 int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
923 uint32_t opcode, uint32_t flags, TDB_DATA data,
924 TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
925 struct timeval *timeout,
928 struct ctdb_client_control_state *state;
930 state = ctdb_control_send(ctdb, destnode, srvid, opcode,
931 flags, data, mem_ctx,
933 return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
941 a process exists call. Returns 0 if process exists, -1 otherwise
943 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
949 data.dptr = (uint8_t*)&pid;
950 data.dsize = sizeof(pid);
952 ret = ctdb_control(ctdb, destnode, 0,
953 CTDB_CONTROL_PROCESS_EXISTS, 0, data,
954 NULL, NULL, &status, NULL, NULL);
956 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
964 get remote statistics
966 int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
972 ret = ctdb_control(ctdb, destnode, 0,
973 CTDB_CONTROL_STATISTICS, 0, tdb_null,
974 ctdb, &data, &res, NULL, NULL);
975 if (ret != 0 || res != 0) {
976 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
980 if (data.dsize != sizeof(struct ctdb_statistics)) {
981 DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
982 (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
986 *status = *(struct ctdb_statistics *)data.dptr;
987 talloc_free(data.dptr);
993 shutdown a remote ctdb node
995 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
997 struct ctdb_client_control_state *state;
999 state = ctdb_control_send(ctdb, destnode, 0,
1000 CTDB_CONTROL_SHUTDOWN, 0, tdb_null,
1001 NULL, &timeout, NULL);
1002 if (state == NULL) {
1003 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
1011 get vnn map from a remote node
1013 int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
1018 struct ctdb_vnn_map_wire *map;
1020 ret = ctdb_control(ctdb, destnode, 0,
1021 CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
1022 mem_ctx, &outdata, &res, &timeout, NULL);
1023 if (ret != 0 || res != 0) {
1024 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
1028 map = (struct ctdb_vnn_map_wire *)outdata.dptr;
1029 if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
1030 outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
1031 DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
1035 (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
1036 CTDB_NO_MEMORY(ctdb, *vnnmap);
1037 (*vnnmap)->generation = map->generation;
1038 (*vnnmap)->size = map->size;
1039 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
1041 CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
1042 memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
1043 talloc_free(outdata.dptr);
1050 get the recovery mode of a remote node
1052 struct ctdb_client_control_state *
1053 ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
1055 return ctdb_control_send(ctdb, destnode, 0,
1056 CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
1057 mem_ctx, &timeout, NULL);
1060 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
1065 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1067 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
1072 *recmode = (uint32_t)res;
1078 int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
1080 struct ctdb_client_control_state *state;
1082 state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
1083 return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
1090 set the recovery mode of a remote node
1092 int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
1098 data.dsize = sizeof(uint32_t);
1099 data.dptr = (unsigned char *)&recmode;
1101 ret = ctdb_control(ctdb, destnode, 0,
1102 CTDB_CONTROL_SET_RECMODE, 0, data,
1103 NULL, NULL, &res, &timeout, NULL);
1104 if (ret != 0 || res != 0) {
1105 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
1115 get the recovery master of a remote node
1117 struct ctdb_client_control_state *
1118 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
1119 struct timeval timeout, uint32_t destnode)
1121 return ctdb_control_send(ctdb, destnode, 0,
1122 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
1123 mem_ctx, &timeout, NULL);
1126 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
1131 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1133 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
1138 *recmaster = (uint32_t)res;
1144 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
1146 struct ctdb_client_control_state *state;
1148 state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
1149 return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
1154 set the recovery master of a remote node
1156 int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
1163 data.dsize = sizeof(uint32_t);
1164 data.dptr = (unsigned char *)&recmaster;
1166 ret = ctdb_control(ctdb, destnode, 0,
1167 CTDB_CONTROL_SET_RECMASTER, 0, data,
1168 NULL, NULL, &res, &timeout, NULL);
1169 if (ret != 0 || res != 0) {
1170 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
1179 get a list of databases off a remote node
1181 int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1182 TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
1188 ret = ctdb_control(ctdb, destnode, 0,
1189 CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
1190 mem_ctx, &outdata, &res, &timeout, NULL);
1191 if (ret != 0 || res != 0) {
1192 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
1196 *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1197 talloc_free(outdata.dptr);
1203 get a list of nodes (vnn and flags ) from a remote node
1205 int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
1206 struct timeval timeout, uint32_t destnode,
1207 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1213 ret = ctdb_control(ctdb, destnode, 0,
1214 CTDB_CONTROL_GET_NODEMAP, 0, tdb_null,
1215 mem_ctx, &outdata, &res, &timeout, NULL);
1216 if (ret == 0 && res == -1 && outdata.dsize == 0) {
1217 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
1218 return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
1220 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1221 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
1225 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1226 talloc_free(outdata.dptr);
1232 old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
1234 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb,
1235 struct timeval timeout, uint32_t destnode,
1236 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1240 struct ctdb_node_mapv4 *nodemapv4;
1243 ret = ctdb_control(ctdb, destnode, 0,
1244 CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null,
1245 mem_ctx, &outdata, &res, &timeout, NULL);
1246 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1247 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
1251 nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
1253 len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
1254 (*nodemap) = talloc_zero_size(mem_ctx, len);
1255 CTDB_NO_MEMORY(ctdb, (*nodemap));
1257 (*nodemap)->num = nodemapv4->num;
1258 for (i=0; i<nodemapv4->num; i++) {
1259 (*nodemap)->nodes[i].pnn = nodemapv4->nodes[i].pnn;
1260 (*nodemap)->nodes[i].flags = nodemapv4->nodes[i].flags;
1261 (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
1262 (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
1265 talloc_free(outdata.dptr);
1271 drop the transport, reload the nodes file and restart the transport
1273 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
1274 struct timeval timeout, uint32_t destnode)
1279 ret = ctdb_control(ctdb, destnode, 0,
1280 CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
1281 NULL, NULL, &res, &timeout, NULL);
1282 if (ret != 0 || res != 0) {
1283 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
1292 set vnn map on a node
1294 int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1295 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
1300 struct ctdb_vnn_map_wire *map;
1303 len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
1304 map = talloc_size(mem_ctx, len);
1305 CTDB_NO_MEMORY(ctdb, map);
1307 map->generation = vnnmap->generation;
1308 map->size = vnnmap->size;
1309 memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
1312 data.dptr = (uint8_t *)map;
1314 ret = ctdb_control(ctdb, destnode, 0,
1315 CTDB_CONTROL_SETVNNMAP, 0, data,
1316 NULL, NULL, &res, &timeout, NULL);
1317 if (ret != 0 || res != 0) {
1318 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
1329 async send for pull database
1331 struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
1332 struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
1333 uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
1336 struct ctdb_control_pulldb *pull;
1337 struct ctdb_client_control_state *state;
1339 pull = talloc(mem_ctx, struct ctdb_control_pulldb);
1340 CTDB_NO_MEMORY_NULL(ctdb, pull);
1343 pull->lmaster = lmaster;
1345 indata.dsize = sizeof(struct ctdb_control_pulldb);
1346 indata.dptr = (unsigned char *)pull;
1348 state = ctdb_control_send(ctdb, destnode, 0,
1349 CTDB_CONTROL_PULL_DB, 0, indata,
1350 mem_ctx, &timeout, NULL);
1357 async recv for pull database
1359 int ctdb_ctrl_pulldb_recv(
1360 struct ctdb_context *ctdb,
1361 TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state,
1367 ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
1368 if ( (ret != 0) || (res != 0) ){
1369 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
1377 pull all keys and records for a specific database on a node
1379 int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode,
1380 uint32_t dbid, uint32_t lmaster,
1381 TALLOC_CTX *mem_ctx, struct timeval timeout,
1384 struct ctdb_client_control_state *state;
1386 state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
1389 return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
1394 change dmaster for all keys in the database to the new value
1396 int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1397 TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
1403 indata.dsize = 2*sizeof(uint32_t);
1404 indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
1406 ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
1407 ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
1409 ret = ctdb_control(ctdb, destnode, 0,
1410 CTDB_CONTROL_SET_DMASTER, 0, indata,
1411 NULL, NULL, &res, &timeout, NULL);
1412 if (ret != 0 || res != 0) {
1413 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
1421 ping a node, return number of clients connected
1423 int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
1428 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0,
1429 tdb_null, NULL, NULL, &res, NULL, NULL);
1437 find the real path to a ltdb
1439 int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1446 data.dptr = (uint8_t *)&dbid;
1447 data.dsize = sizeof(dbid);
1449 ret = ctdb_control(ctdb, destnode, 0,
1450 CTDB_CONTROL_GETDBPATH, 0, data,
1451 mem_ctx, &data, &res, &timeout, NULL);
1452 if (ret != 0 || res != 0) {
1456 (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1457 if ((*path) == NULL) {
1461 talloc_free(data.dptr);
1467 find the name of a db
1469 int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1476 data.dptr = (uint8_t *)&dbid;
1477 data.dsize = sizeof(dbid);
1479 ret = ctdb_control(ctdb, destnode, 0,
1480 CTDB_CONTROL_GET_DBNAME, 0, data,
1481 mem_ctx, &data, &res, &timeout, NULL);
1482 if (ret != 0 || res != 0) {
1486 (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1487 if ((*name) == NULL) {
1491 talloc_free(data.dptr);
1499 int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1500 TALLOC_CTX *mem_ctx, const char *name, bool persistent)
1506 data.dptr = discard_const(name);
1507 data.dsize = strlen(name)+1;
1509 ret = ctdb_control(ctdb, destnode, 0,
1510 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1512 mem_ctx, &data, &res, &timeout, NULL);
1514 if (ret != 0 || res != 0) {
1522 get debug level on a node
1524 int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
1530 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
1531 ctdb, &data, &res, NULL, NULL);
1532 if (ret != 0 || res != 0) {
1535 if (data.dsize != sizeof(int32_t)) {
1536 DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
1537 (unsigned)data.dsize));
1540 *level = *(int32_t *)data.dptr;
1541 talloc_free(data.dptr);
1546 set debug level on a node
1548 int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
1554 data.dptr = (uint8_t *)&level;
1555 data.dsize = sizeof(level);
1557 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data,
1558 NULL, NULL, &res, NULL, NULL);
1559 if (ret != 0 || res != 0) {
1567 get a list of connected nodes
1569 uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
1570 struct timeval timeout,
1571 TALLOC_CTX *mem_ctx,
1572 uint32_t *num_nodes)
1574 struct ctdb_node_map *map=NULL;
1580 ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
1585 nodes = talloc_array(mem_ctx, uint32_t, map->num);
1586 if (nodes == NULL) {
1590 for (i=0;i<map->num;i++) {
1591 if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
1592 nodes[*num_nodes] = map->nodes[i].pnn;
1604 int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
1609 ret = ctdb_control(ctdb, destnode, 0,
1610 CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null,
1611 NULL, NULL, &res, NULL, NULL);
1612 if (ret != 0 || res != 0) {
1613 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
1620 this is the dummy null procedure that all databases support
1622 static int ctdb_null_func(struct ctdb_call_info *call)
1628 this is a plain fetch procedure that all databases support
1630 static int ctdb_fetch_func(struct ctdb_call_info *call)
1632 call->reply_data = &call->record_data;
1637 attach to a specific database - client call
1639 struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name, bool persistent, uint32_t tdb_flags)
1641 struct ctdb_db_context *ctdb_db;
1646 ctdb_db = ctdb_db_handle(ctdb, name);
1651 ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
1652 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
1654 ctdb_db->ctdb = ctdb;
1655 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
1656 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
1658 data.dptr = discard_const(name);
1659 data.dsize = strlen(name)+1;
1661 /* tell ctdb daemon to attach */
1662 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags,
1663 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1664 0, data, ctdb_db, &data, &res, NULL, NULL);
1665 if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
1666 DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
1667 talloc_free(ctdb_db);
1671 ctdb_db->db_id = *(uint32_t *)data.dptr;
1672 talloc_free(data.dptr);
1674 ret = ctdb_ctrl_getdbpath(ctdb, timeval_current_ofs(2, 0), CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
1676 DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
1677 talloc_free(ctdb_db);
1681 tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
1682 if (!ctdb->do_setsched) {
1683 tdb_flags |= TDB_NOMMAP;
1686 ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
1687 if (ctdb_db->ltdb == NULL) {
1688 ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
1689 talloc_free(ctdb_db);
1693 ctdb_db->persistent = persistent;
1695 DLIST_ADD(ctdb->db_list, ctdb_db);
1697 /* add well known functions */
1698 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
1699 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
1706 setup a call for a database
1708 int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
1710 struct ctdb_registered_call *call;
1715 struct ctdb_control_set_call c;
1718 /* this is no longer valid with the separate daemon architecture */
1719 c.db_id = ctdb_db->db_id;
1723 data.dptr = (uint8_t *)&c;
1724 data.dsize = sizeof(c);
1726 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_SET_CALL, 0,
1727 data, NULL, NULL, &status, NULL, NULL);
1728 if (ret != 0 || status != 0) {
1729 DEBUG(DEBUG_ERR,("ctdb_set_call failed for call %u\n", id));
1734 /* also register locally */
1735 call = talloc(ctdb_db, struct ctdb_registered_call);
1739 DLIST_ADD(ctdb_db->calls, call);
1744 struct traverse_state {
1747 ctdb_traverse_func fn;
1752 called on each key during a ctdb_traverse
1754 static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p)
1756 struct traverse_state *state = (struct traverse_state *)p;
1757 struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
1760 if (data.dsize < sizeof(uint32_t) ||
1761 d->length != data.dsize) {
1762 DEBUG(DEBUG_ERR,("Bad data size %u in traverse_handler\n", (unsigned)data.dsize));
1767 key.dsize = d->keylen;
1768 key.dptr = &d->data[0];
1769 data.dsize = d->datalen;
1770 data.dptr = &d->data[d->keylen];
1772 if (key.dsize == 0 && data.dsize == 0) {
1773 /* end of traverse */
1778 if (data.dsize == sizeof(struct ctdb_ltdb_header)) {
1779 /* empty records are deleted records in ctdb */
1783 if (state->fn(ctdb, key, data, state->private_data) != 0) {
1792 start a cluster wide traverse, calling the supplied fn on each record
1793 return the number of records traversed, or -1 on error
1795 int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
1798 struct ctdb_traverse_start t;
1801 uint64_t srvid = (getpid() | 0xFLL<<60);
1802 struct traverse_state state;
1806 state.private_data = private_data;
1809 ret = ctdb_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
1811 DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
1815 t.db_id = ctdb_db->db_id;
1819 data.dptr = (uint8_t *)&t;
1820 data.dsize = sizeof(t);
1822 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START, 0,
1823 data, NULL, NULL, &status, NULL, NULL);
1824 if (ret != 0 || status != 0) {
1825 DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
1826 ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state);
1830 while (!state.done) {
1831 event_loop_once(ctdb_db->ctdb->ev);
1834 ret = ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state);
1836 DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
1843 #define ISASCII(x) ((x>31)&&(x<128))
1845 called on each key during a catdb
1847 static int dumpdb_fn(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p)
1850 FILE *f = (FILE *)p;
1851 struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
1853 fprintf(f, "dmaster: %u\n", h->dmaster);
1854 fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
1856 fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
1857 for (i=0;i<key.dsize;i++) {
1858 if (ISASCII(key.dptr[i])) {
1859 fprintf(f, "%c", key.dptr[i]);
1861 fprintf(f, "\\%02X", key.dptr[i]);
1866 fprintf(f, "data(%u) = \"", (unsigned)data.dsize);
1867 for (i=sizeof(*h);i<data.dsize;i++) {
1868 if (ISASCII(data.dptr[i])) {
1869 fprintf(f, "%c", data.dptr[i]);
1871 fprintf(f, "\\%02X", data.dptr[i]);
1880 convenience function to list all keys to stdout
1882 int ctdb_dump_db(struct ctdb_db_context *ctdb_db, FILE *f)
1884 return ctdb_traverse(ctdb_db, dumpdb_fn, f);
1888 get the pid of a ctdb daemon
1890 int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
1895 ret = ctdb_control(ctdb, destnode, 0,
1896 CTDB_CONTROL_GET_PID, 0, tdb_null,
1897 NULL, NULL, &res, &timeout, NULL);
1899 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
1910 async freeze send control
1912 struct ctdb_client_control_state *
1913 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
1915 return ctdb_control_send(ctdb, destnode, 0,
1916 CTDB_CONTROL_FREEZE, 0, tdb_null,
1917 mem_ctx, &timeout, NULL);
1921 async freeze recv control
1923 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
1928 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1929 if ( (ret != 0) || (res != 0) ){
1930 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
1940 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1942 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1943 struct ctdb_client_control_state *state;
1946 state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode);
1947 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
1948 talloc_free(tmp_ctx);
1956 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1961 ret = ctdb_control(ctdb, destnode, 0,
1962 CTDB_CONTROL_THAW, 0, tdb_null,
1963 NULL, NULL, &res, &timeout, NULL);
1964 if (ret != 0 || res != 0) {
1965 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
1973 get pnn of a node, or -1
1975 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1980 ret = ctdb_control(ctdb, destnode, 0,
1981 CTDB_CONTROL_GET_PNN, 0, tdb_null,
1982 NULL, NULL, &res, &timeout, NULL);
1984 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
1992 get the monitoring mode of a remote node
1994 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
1999 ret = ctdb_control(ctdb, destnode, 0,
2000 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
2001 NULL, NULL, &res, &timeout, NULL);
2003 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
2014 set the monitoring mode of a remote node to active
2016 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2021 ret = ctdb_control(ctdb, destnode, 0,
2022 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
2023 NULL, NULL,NULL, &timeout, NULL);
2025 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
2035 set the monitoring mode of a remote node to disable
2037 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2042 ret = ctdb_control(ctdb, destnode, 0,
2043 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
2044 NULL, NULL, NULL, &timeout, NULL);
2046 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
2058 sent to a node to make it take over an ip address
2060 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
2061 uint32_t destnode, struct ctdb_public_ip *ip)
2064 struct ctdb_public_ipv4 ipv4;
2068 if (ip->addr.sa.sa_family == AF_INET) {
2070 ipv4.sin = ip->addr.ip;
2072 data.dsize = sizeof(ipv4);
2073 data.dptr = (uint8_t *)&ipv4;
2075 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
2076 NULL, &res, &timeout, NULL);
2078 data.dsize = sizeof(*ip);
2079 data.dptr = (uint8_t *)ip;
2081 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
2082 NULL, &res, &timeout, NULL);
2085 if (ret != 0 || res != 0) {
2086 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
2095 sent to a node to make it release an ip address
2097 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
2098 uint32_t destnode, struct ctdb_public_ip *ip)
2101 struct ctdb_public_ipv4 ipv4;
2105 if (ip->addr.sa.sa_family == AF_INET) {
2107 ipv4.sin = ip->addr.ip;
2109 data.dsize = sizeof(ipv4);
2110 data.dptr = (uint8_t *)&ipv4;
2112 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
2113 NULL, &res, &timeout, NULL);
2115 data.dsize = sizeof(*ip);
2116 data.dptr = (uint8_t *)ip;
2118 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
2119 NULL, &res, &timeout, NULL);
2122 if (ret != 0 || res != 0) {
2123 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
2134 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
2135 struct timeval timeout,
2137 const char *name, uint32_t *value)
2139 struct ctdb_control_get_tunable *t;
2140 TDB_DATA data, outdata;
2144 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
2145 data.dptr = talloc_size(ctdb, data.dsize);
2146 CTDB_NO_MEMORY(ctdb, data.dptr);
2148 t = (struct ctdb_control_get_tunable *)data.dptr;
2149 t->length = strlen(name)+1;
2150 memcpy(t->name, name, t->length);
2152 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
2153 &outdata, &res, &timeout, NULL);
2154 talloc_free(data.dptr);
2155 if (ret != 0 || res != 0) {
2156 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
2160 if (outdata.dsize != sizeof(uint32_t)) {
2161 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
2162 talloc_free(outdata.dptr);
2166 *value = *(uint32_t *)outdata.dptr;
2167 talloc_free(outdata.dptr);
2175 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
2176 struct timeval timeout,
2178 const char *name, uint32_t value)
2180 struct ctdb_control_set_tunable *t;
2185 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
2186 data.dptr = talloc_size(ctdb, data.dsize);
2187 CTDB_NO_MEMORY(ctdb, data.dptr);
2189 t = (struct ctdb_control_set_tunable *)data.dptr;
2190 t->length = strlen(name)+1;
2191 memcpy(t->name, name, t->length);
2194 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
2195 NULL, &res, &timeout, NULL);
2196 talloc_free(data.dptr);
2197 if (ret != 0 || res != 0) {
2198 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
2208 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
2209 struct timeval timeout,
2211 TALLOC_CTX *mem_ctx,
2212 const char ***list, uint32_t *count)
2217 struct ctdb_control_list_tunable *t;
2220 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
2221 mem_ctx, &outdata, &res, &timeout, NULL);
2222 if (ret != 0 || res != 0) {
2223 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
2227 t = (struct ctdb_control_list_tunable *)outdata.dptr;
2228 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
2229 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
2230 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
2231 talloc_free(outdata.dptr);
2235 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
2236 CTDB_NO_MEMORY(ctdb, p);
2238 talloc_free(outdata.dptr);
2243 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
2244 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
2245 CTDB_NO_MEMORY(ctdb, *list);
2246 (*list)[*count] = talloc_strdup(*list, s);
2247 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
2257 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
2258 struct timeval timeout, uint32_t destnode,
2259 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2265 ret = ctdb_control(ctdb, destnode, 0,
2266 CTDB_CONTROL_GET_PUBLIC_IPS, 0, tdb_null,
2267 mem_ctx, &outdata, &res, &timeout, NULL);
2268 if (ret == 0 && res == -1) {
2269 DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
2270 return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
2272 if (ret != 0 || res != 0) {
2273 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
2277 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
2278 talloc_free(outdata.dptr);
2283 int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
2284 struct timeval timeout, uint32_t destnode,
2285 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2290 struct ctdb_all_public_ipsv4 *ipsv4;
2292 ret = ctdb_control(ctdb, destnode, 0,
2293 CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null,
2294 mem_ctx, &outdata, &res, &timeout, NULL);
2295 if (ret != 0 || res != 0) {
2296 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
2300 ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
2301 len = offsetof(struct ctdb_all_public_ips, ips) +
2302 ipsv4->num*sizeof(struct ctdb_public_ip);
2303 *ips = talloc_zero_size(mem_ctx, len);
2304 CTDB_NO_MEMORY(ctdb, *ips);
2305 (*ips)->num = ipsv4->num;
2306 for (i=0; i<ipsv4->num; i++) {
2307 (*ips)->ips[i].pnn = ipsv4->ips[i].pnn;
2308 (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
2311 talloc_free(outdata.dptr);
2317 set/clear the permanent disabled bit on a remote node
2319 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
2320 uint32_t set, uint32_t clear)
2324 struct ctdb_node_map *nodemap=NULL;
2325 struct ctdb_node_flag_change c;
2326 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2331 /* find the recovery master */
2332 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
2334 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
2335 talloc_free(tmp_ctx);
2340 /* read the node flags from the recmaster */
2341 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
2343 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
2344 talloc_free(tmp_ctx);
2347 if (destnode >= nodemap->num) {
2348 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
2349 talloc_free(tmp_ctx);
2354 c.old_flags = nodemap->nodes[destnode].flags;
2355 c.new_flags = c.old_flags;
2357 c.new_flags &= ~clear;
2359 data.dsize = sizeof(c);
2360 data.dptr = (unsigned char *)&c;
2362 /* send the flags update to all connected nodes */
2363 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
2365 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
2367 timeout, false, data,
2370 DEBUG(DEBUG_ERR, (__location__ " ctdb_control to disable node failed\n"));
2372 talloc_free(tmp_ctx);
2376 talloc_free(tmp_ctx);
2384 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
2385 struct timeval timeout,
2387 struct ctdb_tunable *tunables)
2393 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
2394 &outdata, &res, &timeout, NULL);
2395 if (ret != 0 || res != 0) {
2396 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
2400 if (outdata.dsize != sizeof(*tunables)) {
2401 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
2402 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
2406 *tunables = *(struct ctdb_tunable *)outdata.dptr;
2407 talloc_free(outdata.dptr);
2412 add a public address to a node
2414 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
2415 struct timeval timeout,
2417 struct ctdb_control_ip_iface *pub)
2423 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2424 data.dptr = (unsigned char *)pub;
2426 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
2427 NULL, &res, &timeout, NULL);
2428 if (ret != 0 || res != 0) {
2429 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
2437 delete a public address from a node
2439 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
2440 struct timeval timeout,
2442 struct ctdb_control_ip_iface *pub)
2448 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2449 data.dptr = (unsigned char *)pub;
2451 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
2452 NULL, &res, &timeout, NULL);
2453 if (ret != 0 || res != 0) {
2454 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
2462 kill a tcp connection
2464 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
2465 struct timeval timeout,
2467 struct ctdb_control_killtcp *killtcp)
2473 data.dsize = sizeof(struct ctdb_control_killtcp);
2474 data.dptr = (unsigned char *)killtcp;
2476 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
2477 NULL, &res, &timeout, NULL);
2478 if (ret != 0 || res != 0) {
2479 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
2489 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
2490 struct timeval timeout,
2492 ctdb_sock_addr *addr,
2498 struct ctdb_control_gratious_arp *gratious_arp;
2499 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2502 len = strlen(ifname)+1;
2503 gratious_arp = talloc_size(tmp_ctx,
2504 offsetof(struct ctdb_control_gratious_arp, iface) + len);
2505 CTDB_NO_MEMORY(ctdb, gratious_arp);
2507 gratious_arp->addr = *addr;
2508 gratious_arp->len = len;
2509 memcpy(&gratious_arp->iface[0], ifname, len);
2512 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
2513 data.dptr = (unsigned char *)gratious_arp;
2515 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
2516 NULL, &res, &timeout, NULL);
2517 if (ret != 0 || res != 0) {
2518 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
2519 talloc_free(tmp_ctx);
2523 talloc_free(tmp_ctx);
2528 get a list of all tcp tickles that a node knows about for a particular vnn
2530 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
2531 struct timeval timeout, uint32_t destnode,
2532 TALLOC_CTX *mem_ctx,
2533 ctdb_sock_addr *addr,
2534 struct ctdb_control_tcp_tickle_list **list)
2537 TDB_DATA data, outdata;
2540 data.dptr = (uint8_t*)addr;
2541 data.dsize = sizeof(ctdb_sock_addr);
2543 ret = ctdb_control(ctdb, destnode, 0,
2544 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
2545 mem_ctx, &outdata, &status, NULL, NULL);
2546 if (ret != 0 || status != 0) {
2547 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
2551 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
2557 register a server id
2559 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
2560 struct timeval timeout,
2561 struct ctdb_server_id *id)
2567 data.dsize = sizeof(struct ctdb_server_id);
2568 data.dptr = (unsigned char *)id;
2570 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2571 CTDB_CONTROL_REGISTER_SERVER_ID,
2573 NULL, &res, &timeout, NULL);
2574 if (ret != 0 || res != 0) {
2575 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
2583 unregister a server id
2585 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
2586 struct timeval timeout,
2587 struct ctdb_server_id *id)
2593 data.dsize = sizeof(struct ctdb_server_id);
2594 data.dptr = (unsigned char *)id;
2596 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2597 CTDB_CONTROL_UNREGISTER_SERVER_ID,
2599 NULL, &res, &timeout, NULL);
2600 if (ret != 0 || res != 0) {
2601 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
2610 check if a server id exists
2612 if a server id does exist, return *status == 1, otherwise *status == 0
2614 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
2615 struct timeval timeout,
2617 struct ctdb_server_id *id,
2624 data.dsize = sizeof(struct ctdb_server_id);
2625 data.dptr = (unsigned char *)id;
2627 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
2629 NULL, &res, &timeout, NULL);
2631 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
2645 get the list of server ids that are registered on a node
2647 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
2648 TALLOC_CTX *mem_ctx,
2649 struct timeval timeout, uint32_t destnode,
2650 struct ctdb_server_id_list **svid_list)
2656 ret = ctdb_control(ctdb, destnode, 0,
2657 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
2658 mem_ctx, &outdata, &res, &timeout, NULL);
2659 if (ret != 0 || res != 0) {
2660 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
2664 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
2670 initialise the ctdb daemon for client applications
2672 NOTE: In current code the daemon does not fork. This is for testing purposes only
2673 and to simplify the code.
2675 struct ctdb_context *ctdb_init(struct event_context *ev)
2678 struct ctdb_context *ctdb;
2680 ctdb = talloc_zero(ev, struct ctdb_context);
2682 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
2686 ctdb->idr = idr_init(ctdb);
2687 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
2689 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
2691 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
2703 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
2705 ctdb->flags |= flags;
2709 setup the local socket name
2711 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
2713 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
2714 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
2720 return the pnn of this node
2722 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
2729 get the uptime of a remote node
2731 struct ctdb_client_control_state *
2732 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
2734 return ctdb_control_send(ctdb, destnode, 0,
2735 CTDB_CONTROL_UPTIME, 0, tdb_null,
2736 mem_ctx, &timeout, NULL);
2739 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
2745 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
2746 if (ret != 0 || res != 0) {
2747 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
2751 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
2756 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
2758 struct ctdb_client_control_state *state;
2760 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
2761 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
2765 send a control to execute the "recovered" event script on a node
2767 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2772 ret = ctdb_control(ctdb, destnode, 0,
2773 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
2774 NULL, NULL, &status, &timeout, NULL);
2775 if (ret != 0 || status != 0) {
2776 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
2784 callback for the async helpers used when sending the same control
2785 to multiple nodes in parallell.
2787 static void async_callback(struct ctdb_client_control_state *state)
2789 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
2790 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
2794 uint32_t destnode = state->c->hdr.destnode;
2796 /* one more node has responded with recmode data */
2799 /* if we failed to push the db, then return an error and let
2800 the main loop try again.
2802 if (state->state != CTDB_CONTROL_DONE) {
2803 if ( !data->dont_log_errors) {
2804 DEBUG(DEBUG_ERR,("Async operation failed with state %d\n opcode:%u", state->state, data->opcode));
2807 if (data->fail_callback) {
2808 data->fail_callback(ctdb, destnode, res, outdata,
2809 data->callback_data);
2814 state->async.fn = NULL;
2816 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
2817 if ((ret != 0) || (res != 0)) {
2818 if ( !data->dont_log_errors) {
2819 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
2822 if (data->fail_callback) {
2823 data->fail_callback(ctdb, destnode, res, outdata,
2824 data->callback_data);
2827 if ((ret == 0) && (data->callback != NULL)) {
2828 data->callback(ctdb, destnode, res, outdata,
2829 data->callback_data);
2834 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
2836 /* set up the callback functions */
2837 state->async.fn = async_callback;
2838 state->async.private_data = data;
2840 /* one more control to wait for to complete */
2845 /* wait for up to the maximum number of seconds allowed
2846 or until all nodes we expect a response from has replied
2848 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
2850 while (data->count > 0) {
2851 event_loop_once(ctdb->ev);
2853 if (data->fail_count != 0) {
2854 if (!data->dont_log_errors) {
2855 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
2865 perform a simple control on the listed nodes
2866 The control cannot return data
2868 int ctdb_client_async_control(struct ctdb_context *ctdb,
2869 enum ctdb_controls opcode,
2871 struct timeval timeout,
2872 bool dont_log_errors,
2874 client_async_callback client_callback,
2875 client_async_callback fail_callback,
2876 void *callback_data)
2878 struct client_async_data *async_data;
2879 struct ctdb_client_control_state *state;
2882 async_data = talloc_zero(ctdb, struct client_async_data);
2883 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
2884 async_data->dont_log_errors = dont_log_errors;
2885 async_data->callback = client_callback;
2886 async_data->fail_callback = fail_callback;
2887 async_data->callback_data = callback_data;
2888 async_data->opcode = opcode;
2890 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
2892 /* loop over all nodes and send an async control to each of them */
2893 for (j=0; j<num_nodes; j++) {
2894 uint32_t pnn = nodes[j];
2896 state = ctdb_control_send(ctdb, pnn, 0, opcode,
2897 0, data, async_data, &timeout, NULL);
2898 if (state == NULL) {
2899 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
2900 talloc_free(async_data);
2904 ctdb_client_async_add(async_data, state);
2907 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
2908 talloc_free(async_data);
2912 talloc_free(async_data);
2916 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
2917 struct ctdb_vnn_map *vnn_map,
2918 TALLOC_CTX *mem_ctx,
2921 int i, j, num_nodes;
2924 for (i=num_nodes=0;i<vnn_map->size;i++) {
2925 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2931 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2932 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2934 for (i=j=0;i<vnn_map->size;i++) {
2935 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2938 nodes[j++] = vnn_map->map[i];
2944 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
2945 struct ctdb_node_map *node_map,
2946 TALLOC_CTX *mem_ctx,
2949 int i, j, num_nodes;
2952 for (i=num_nodes=0;i<node_map->num;i++) {
2953 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2956 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2962 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2963 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2965 for (i=j=0;i<node_map->num;i++) {
2966 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2969 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2972 nodes[j++] = node_map->nodes[i].pnn;
2978 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
2979 struct ctdb_node_map *node_map,
2980 TALLOC_CTX *mem_ctx,
2983 int i, j, num_nodes;
2986 for (i=num_nodes=0;i<node_map->num;i++) {
2987 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
2990 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2996 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2997 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2999 for (i=j=0;i<node_map->num;i++) {
3000 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3003 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3006 nodes[j++] = node_map->nodes[i].pnn;
3013 this is used to test if a pnn lock exists and if it exists will return
3014 the number of connections that pnn has reported or -1 if that recovery
3015 daemon is not running.
3018 ctdb_read_pnn_lock(int fd, int32_t pnn)
3023 lock.l_type = F_WRLCK;
3024 lock.l_whence = SEEK_SET;
3029 if (fcntl(fd, F_GETLK, &lock) != 0) {
3030 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3034 if (lock.l_type == F_UNLCK) {
3038 if (pread(fd, &c, 1, pnn) == -1) {
3039 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3047 get capabilities of a remote node
3049 struct ctdb_client_control_state *
3050 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3052 return ctdb_control_send(ctdb, destnode, 0,
3053 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3054 mem_ctx, &timeout, NULL);
3057 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3063 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3064 if ( (ret != 0) || (res != 0) ) {
3065 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3070 *capabilities = *((uint32_t *)outdata.dptr);
3076 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3078 struct ctdb_client_control_state *state;
3079 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3082 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3083 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3084 talloc_free(tmp_ctx);
3088 struct ctdb_transaction_handle {
3089 struct ctdb_db_context *ctdb_db;
3091 /* we store the reads and writes done under a transaction one
3092 list stores both reads and writes, the other just writes
3094 struct ctdb_marshall_buffer *m_all;
3095 struct ctdb_marshall_buffer *m_write;
3098 /* start a transaction on a database */
3099 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
3101 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3105 /* start a transaction on a database */
3106 static int ctdb_transaction_fetch_start(struct ctdb_transaction_handle *h)
3108 struct ctdb_record_handle *rh;
3110 struct ctdb_ltdb_header header;
3111 TALLOC_CTX *tmp_ctx;
3112 const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
3114 struct ctdb_db_context *ctdb_db = h->ctdb_db;
3116 key.dptr = discard_const(keyname);
3117 key.dsize = strlen(keyname);
3119 if (!ctdb_db->persistent) {
3120 DEBUG(DEBUG_ERR,(__location__ " Attempted transaction on non-persistent database\n"));
3125 tmp_ctx = talloc_new(h);
3127 rh = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, NULL);
3129 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch_lock database\n"));
3130 talloc_free(tmp_ctx);
3135 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3137 DEBUG(DEBUG_ERR,(__location__ " Failed to start tdb transaction\n"));
3138 talloc_free(tmp_ctx);
3142 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, NULL);
3143 if (ret != 0 || header.dmaster != ctdb_db->ctdb->pnn) {
3144 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3145 talloc_free(tmp_ctx);
3149 talloc_free(tmp_ctx);
3155 /* start a transaction on a database */
3156 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
3157 TALLOC_CTX *mem_ctx)
3159 struct ctdb_transaction_handle *h;
3162 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
3164 DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
3168 h->ctdb_db = ctdb_db;
3170 ret = ctdb_transaction_fetch_start(h);
3176 talloc_set_destructor(h, ctdb_transaction_destructor);
3184 fetch a record inside a transaction
3186 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
3187 TALLOC_CTX *mem_ctx,
3188 TDB_DATA key, TDB_DATA *data)
3190 struct ctdb_ltdb_header header;
3193 ZERO_STRUCT(header);
3195 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
3196 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3197 /* record doesn't exist yet */
3206 if (!h->in_replay) {
3207 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
3208 if (h->m_all == NULL) {
3209 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3218 stores a record inside a transaction
3220 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
3221 TDB_DATA key, TDB_DATA data)
3223 TALLOC_CTX *tmp_ctx = talloc_new(h);
3224 struct ctdb_ltdb_header header;
3228 ZERO_STRUCT(header);
3230 /* we need the header so we can update the RSN */
3231 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
3232 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3233 /* the record doesn't exist - create one with us as dmaster.
3234 This is only safe because we are in a transaction and this
3235 is a persistent database */
3236 ZERO_STRUCT(header);
3237 } else if (ret != 0) {
3238 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
3239 talloc_free(tmp_ctx);
3243 if (data.dsize == olddata.dsize &&
3244 memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
3245 /* save writing the same data */
3246 talloc_free(tmp_ctx);
3250 header.dmaster = h->ctdb_db->ctdb->pnn;
3253 if (!h->in_replay) {
3254 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
3255 if (h->m_all == NULL) {
3256 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3257 talloc_free(tmp_ctx);
3262 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
3263 if (h->m_write == NULL) {
3264 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3265 talloc_free(tmp_ctx);
3269 ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
3271 talloc_free(tmp_ctx);
3277 replay a transaction
3279 static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
3282 struct ctdb_rec_data *rec = NULL;
3284 h->in_replay = true;
3285 talloc_free(h->m_write);
3288 ret = ctdb_transaction_fetch_start(h);
3293 for (i=0;i<h->m_all->count;i++) {
3296 rec = ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
3298 DEBUG(DEBUG_ERR, (__location__ " Out of records in ctdb_replay_transaction?\n"));
3302 if (rec->reqid == 0) {
3304 if (ctdb_transaction_store(h, key, data) != 0) {
3309 TALLOC_CTX *tmp_ctx = talloc_new(h);
3311 if (ctdb_transaction_fetch(h, tmp_ctx, key, &data2) != 0) {
3312 talloc_free(tmp_ctx);
3315 if (data2.dsize != data.dsize ||
3316 memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
3317 /* the record has changed on us - we have to give up */
3318 talloc_free(tmp_ctx);
3321 talloc_free(tmp_ctx);
3328 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3334 commit a transaction
3336 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
3340 struct ctdb_context *ctdb = h->ctdb_db->ctdb;
3341 struct timeval timeout;
3342 enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
3344 talloc_set_destructor(h, NULL);
3346 /* our commit strategy is quite complex.
3348 - we first try to commit the changes to all other nodes
3350 - if that works, then we commit locally and we are done
3352 - if a commit on another node fails, then we need to cancel
3353 the transaction, then restart the transaction (thus
3354 opening a window of time for a pending recovery to
3355 complete), then replay the transaction, checking all the
3356 reads and writes (checking that reads give the same data,
3357 and writes succeed). Then we retry the transaction to the
3362 if (h->m_write == NULL) {
3363 /* no changes were made */
3364 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3369 /* tell ctdbd to commit to the other nodes */
3370 timeout = timeval_current_ofs(1, 0);
3371 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3372 retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY, 0,
3373 ctdb_marshall_finish(h->m_write), NULL, NULL, &status,
3375 if (ret != 0 || status != 0) {
3376 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3380 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3382 /* work out what error code we will give if we
3383 have to fail the operation */
3384 switch ((enum ctdb_trans2_commit_error)status) {
3385 case CTDB_TRANS2_COMMIT_SUCCESS:
3386 case CTDB_TRANS2_COMMIT_SOMEFAIL:
3387 case CTDB_TRANS2_COMMIT_TIMEOUT:
3388 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3390 case CTDB_TRANS2_COMMIT_ALLFAIL:
3391 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
3396 if (++retries == 10) {
3397 DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
3398 h->ctdb_db->db_id, retries, (unsigned)failure_control));
3399 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3400 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3401 tdb_null, NULL, NULL, NULL, NULL, NULL);
3406 if (ctdb_replay_transaction(h) != 0) {
3407 DEBUG(DEBUG_ERR,(__location__ " Failed to replay transaction\n"));
3408 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3409 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3410 tdb_null, NULL, NULL, NULL, NULL, NULL);
3416 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3419 /* do the real commit locally */
3420 ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
3422 DEBUG(DEBUG_ERR,(__location__ " Failed to commit transaction\n"));
3423 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3424 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3425 tdb_null, NULL, NULL, NULL, NULL, NULL);
3430 /* tell ctdbd that we are finished with our local commit */
3431 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3432 CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
3433 tdb_null, NULL, NULL, NULL, NULL, NULL);
3439 recovery daemon ping to main daemon
3441 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
3446 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
3447 ctdb, NULL, &res, NULL, NULL);
3448 if (ret != 0 || res != 0) {
3449 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
3456 /* when forking the main daemon and the child process needs to connect back
3457 * to the daemon as a client process, this function can be used to change
3458 * the ctdb context from daemon into client mode
3460 int switch_from_server_to_client(struct ctdb_context *ctdb)
3464 /* shutdown the transport */
3465 if (ctdb->methods) {
3466 ctdb->methods->shutdown(ctdb);
3469 /* get a new event context */
3470 talloc_free(ctdb->ev);
3471 ctdb->ev = event_context_init(ctdb);
3473 close(ctdb->daemon.sd);
3474 ctdb->daemon.sd = -1;
3476 /* the client does not need to be realtime */
3477 if (ctdb->do_setsched) {
3478 ctdb_restore_scheduler(ctdb);
3481 /* initialise ctdb */
3482 ret = ctdb_socket_connect(ctdb);
3484 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
3492 tell the main daemon we are starting a new monitor event script
3494 int ctdb_ctrl_event_script_init(struct ctdb_context *ctdb)
3499 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_INIT, 0, tdb_null,
3500 ctdb, NULL, &res, NULL, NULL);
3501 if (ret != 0 || res != 0) {
3502 DEBUG(DEBUG_ERR,("Failed to send event_script_init\n"));
3510 tell the main daemon we are starting a new monitor event script
3512 int ctdb_ctrl_event_script_finished(struct ctdb_context *ctdb)
3517 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_FINISHED, 0, tdb_null,
3518 ctdb, NULL, &res, NULL, NULL);
3519 if (ret != 0 || res != 0) {
3520 DEBUG(DEBUG_ERR,("Failed to send event_script_init\n"));
3528 tell the main daemon we are starting to run an eventscript
3530 int ctdb_ctrl_event_script_start(struct ctdb_context *ctdb, const char *name)
3536 data.dptr = discard_const(name);
3537 data.dsize = strlen(name)+1;
3539 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_START, 0, data,
3540 ctdb, NULL, &res, NULL, NULL);
3541 if (ret != 0 || res != 0) {
3542 DEBUG(DEBUG_ERR,("Failed to send event_script_start\n"));
3550 tell the main daemon the status of the script we ran
3552 int ctdb_ctrl_event_script_stop(struct ctdb_context *ctdb, int32_t result)
3558 data.dptr = (uint8_t *)&result;
3559 data.dsize = sizeof(result);
3561 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_STOP, 0, data,
3562 ctdb, NULL, &res, NULL, NULL);
3563 if (ret != 0 || res != 0) {
3564 DEBUG(DEBUG_ERR,("Failed to send event_script_stop\n"));
3573 get the status of running the monitor eventscripts
3575 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
3576 struct timeval timeout, uint32_t destnode,
3577 TALLOC_CTX *mem_ctx,
3578 struct ctdb_monitoring_wire **script_status)
3584 ret = ctdb_control(ctdb, destnode, 0,
3585 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, tdb_null,
3586 mem_ctx, &outdata, &res, &timeout, NULL);
3587 if (ret != 0 || res != 0 || outdata.dsize == 0) {
3588 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
3592 *script_status = (struct ctdb_monitoring_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
3593 talloc_free(outdata.dptr);
3599 tell the main daemon how long it took to lock the reclock file
3601 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
3607 data.dptr = (uint8_t *)&latency;
3608 data.dsize = sizeof(latency);
3610 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
3611 ctdb, NULL, &res, NULL, NULL);
3612 if (ret != 0 || res != 0) {
3613 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
3621 get the name of the reclock file
3623 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
3624 uint32_t destnode, TALLOC_CTX *mem_ctx,
3631 ret = ctdb_control(ctdb, destnode, 0,
3632 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
3633 mem_ctx, &data, &res, &timeout, NULL);
3634 if (ret != 0 || res != 0) {
3638 if (data.dsize == 0) {
3641 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
3643 talloc_free(data.dptr);
3649 set the reclock filename for a node
3651 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
3657 if (reclock == NULL) {
3661 data.dsize = strlen(reclock) + 1;
3662 data.dptr = discard_const(reclock);
3665 ret = ctdb_control(ctdb, destnode, 0,
3666 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
3667 NULL, NULL, &res, &timeout, NULL);
3668 if (ret != 0 || res != 0) {
3669 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
3679 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3684 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
3685 ctdb, NULL, &res, &timeout, NULL);
3686 if (ret != 0 || res != 0) {
3687 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
3697 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3701 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
3702 ctdb, NULL, NULL, &timeout, NULL);
3704 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
3712 set the natgw state for a node
3714 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
3720 data.dsize = sizeof(natgwstate);
3721 data.dptr = (uint8_t *)&natgwstate;
3723 ret = ctdb_control(ctdb, destnode, 0,
3724 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
3725 NULL, NULL, &res, &timeout, NULL);
3726 if (ret != 0 || res != 0) {
3727 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
3735 set the lmaster role for a node
3737 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
3743 data.dsize = sizeof(lmasterrole);
3744 data.dptr = (uint8_t *)&lmasterrole;
3746 ret = ctdb_control(ctdb, destnode, 0,
3747 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
3748 NULL, NULL, &res, &timeout, NULL);
3749 if (ret != 0 || res != 0) {
3750 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
3758 set the recmaster role for a node
3760 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
3766 data.dsize = sizeof(recmasterrole);
3767 data.dptr = (uint8_t *)&recmasterrole;
3769 ret = ctdb_control(ctdb, destnode, 0,
3770 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
3771 NULL, NULL, &res, &timeout, NULL);
3772 if (ret != 0 || res != 0) {
3773 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));