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, uint32_t priority)
1915 return ctdb_control_send(ctdb, destnode, priority,
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"));
1938 freeze databases of a certain priority
1940 int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
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, priority);
1947 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
1948 talloc_free(tmp_ctx);
1953 /* Freeze all databases */
1954 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1958 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
1959 if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
1967 thaw databases of a certain priority
1969 int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
1974 ret = ctdb_control(ctdb, destnode, priority,
1975 CTDB_CONTROL_THAW, 0, tdb_null,
1976 NULL, NULL, &res, &timeout, NULL);
1977 if (ret != 0 || res != 0) {
1978 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
1985 /* thaw all databases */
1986 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1988 return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
1992 get pnn of a node, or -1
1994 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1999 ret = ctdb_control(ctdb, destnode, 0,
2000 CTDB_CONTROL_GET_PNN, 0, tdb_null,
2001 NULL, NULL, &res, &timeout, NULL);
2003 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
2011 get the monitoring mode of a remote node
2013 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
2018 ret = ctdb_control(ctdb, destnode, 0,
2019 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
2020 NULL, NULL, &res, &timeout, NULL);
2022 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
2033 set the monitoring mode of a remote node to active
2035 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2040 ret = ctdb_control(ctdb, destnode, 0,
2041 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
2042 NULL, NULL,NULL, &timeout, NULL);
2044 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
2054 set the monitoring mode of a remote node to disable
2056 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2061 ret = ctdb_control(ctdb, destnode, 0,
2062 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
2063 NULL, NULL, NULL, &timeout, NULL);
2065 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
2077 sent to a node to make it take over an ip address
2079 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
2080 uint32_t destnode, struct ctdb_public_ip *ip)
2083 struct ctdb_public_ipv4 ipv4;
2087 if (ip->addr.sa.sa_family == AF_INET) {
2089 ipv4.sin = ip->addr.ip;
2091 data.dsize = sizeof(ipv4);
2092 data.dptr = (uint8_t *)&ipv4;
2094 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
2095 NULL, &res, &timeout, NULL);
2097 data.dsize = sizeof(*ip);
2098 data.dptr = (uint8_t *)ip;
2100 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
2101 NULL, &res, &timeout, NULL);
2104 if (ret != 0 || res != 0) {
2105 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
2114 sent to a node to make it release an ip address
2116 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
2117 uint32_t destnode, struct ctdb_public_ip *ip)
2120 struct ctdb_public_ipv4 ipv4;
2124 if (ip->addr.sa.sa_family == AF_INET) {
2126 ipv4.sin = ip->addr.ip;
2128 data.dsize = sizeof(ipv4);
2129 data.dptr = (uint8_t *)&ipv4;
2131 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
2132 NULL, &res, &timeout, NULL);
2134 data.dsize = sizeof(*ip);
2135 data.dptr = (uint8_t *)ip;
2137 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
2138 NULL, &res, &timeout, NULL);
2141 if (ret != 0 || res != 0) {
2142 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
2153 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
2154 struct timeval timeout,
2156 const char *name, uint32_t *value)
2158 struct ctdb_control_get_tunable *t;
2159 TDB_DATA data, outdata;
2163 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
2164 data.dptr = talloc_size(ctdb, data.dsize);
2165 CTDB_NO_MEMORY(ctdb, data.dptr);
2167 t = (struct ctdb_control_get_tunable *)data.dptr;
2168 t->length = strlen(name)+1;
2169 memcpy(t->name, name, t->length);
2171 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
2172 &outdata, &res, &timeout, NULL);
2173 talloc_free(data.dptr);
2174 if (ret != 0 || res != 0) {
2175 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
2179 if (outdata.dsize != sizeof(uint32_t)) {
2180 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
2181 talloc_free(outdata.dptr);
2185 *value = *(uint32_t *)outdata.dptr;
2186 talloc_free(outdata.dptr);
2194 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
2195 struct timeval timeout,
2197 const char *name, uint32_t value)
2199 struct ctdb_control_set_tunable *t;
2204 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
2205 data.dptr = talloc_size(ctdb, data.dsize);
2206 CTDB_NO_MEMORY(ctdb, data.dptr);
2208 t = (struct ctdb_control_set_tunable *)data.dptr;
2209 t->length = strlen(name)+1;
2210 memcpy(t->name, name, t->length);
2213 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
2214 NULL, &res, &timeout, NULL);
2215 talloc_free(data.dptr);
2216 if (ret != 0 || res != 0) {
2217 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
2227 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
2228 struct timeval timeout,
2230 TALLOC_CTX *mem_ctx,
2231 const char ***list, uint32_t *count)
2236 struct ctdb_control_list_tunable *t;
2239 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
2240 mem_ctx, &outdata, &res, &timeout, NULL);
2241 if (ret != 0 || res != 0) {
2242 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
2246 t = (struct ctdb_control_list_tunable *)outdata.dptr;
2247 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
2248 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
2249 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
2250 talloc_free(outdata.dptr);
2254 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
2255 CTDB_NO_MEMORY(ctdb, p);
2257 talloc_free(outdata.dptr);
2262 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
2263 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
2264 CTDB_NO_MEMORY(ctdb, *list);
2265 (*list)[*count] = talloc_strdup(*list, s);
2266 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
2276 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
2277 struct timeval timeout, uint32_t destnode,
2278 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2284 ret = ctdb_control(ctdb, destnode, 0,
2285 CTDB_CONTROL_GET_PUBLIC_IPS, 0, tdb_null,
2286 mem_ctx, &outdata, &res, &timeout, NULL);
2287 if (ret == 0 && res == -1) {
2288 DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
2289 return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
2291 if (ret != 0 || res != 0) {
2292 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
2296 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
2297 talloc_free(outdata.dptr);
2302 int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
2303 struct timeval timeout, uint32_t destnode,
2304 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2309 struct ctdb_all_public_ipsv4 *ipsv4;
2311 ret = ctdb_control(ctdb, destnode, 0,
2312 CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null,
2313 mem_ctx, &outdata, &res, &timeout, NULL);
2314 if (ret != 0 || res != 0) {
2315 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
2319 ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
2320 len = offsetof(struct ctdb_all_public_ips, ips) +
2321 ipsv4->num*sizeof(struct ctdb_public_ip);
2322 *ips = talloc_zero_size(mem_ctx, len);
2323 CTDB_NO_MEMORY(ctdb, *ips);
2324 (*ips)->num = ipsv4->num;
2325 for (i=0; i<ipsv4->num; i++) {
2326 (*ips)->ips[i].pnn = ipsv4->ips[i].pnn;
2327 (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
2330 talloc_free(outdata.dptr);
2336 set/clear the permanent disabled bit on a remote node
2338 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
2339 uint32_t set, uint32_t clear)
2343 struct ctdb_node_map *nodemap=NULL;
2344 struct ctdb_node_flag_change c;
2345 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2350 /* find the recovery master */
2351 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
2353 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
2354 talloc_free(tmp_ctx);
2359 /* read the node flags from the recmaster */
2360 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
2362 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
2363 talloc_free(tmp_ctx);
2366 if (destnode >= nodemap->num) {
2367 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
2368 talloc_free(tmp_ctx);
2373 c.old_flags = nodemap->nodes[destnode].flags;
2374 c.new_flags = c.old_flags;
2376 c.new_flags &= ~clear;
2378 data.dsize = sizeof(c);
2379 data.dptr = (unsigned char *)&c;
2381 /* send the flags update to all connected nodes */
2382 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
2384 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
2386 timeout, false, data,
2389 DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
2391 talloc_free(tmp_ctx);
2395 talloc_free(tmp_ctx);
2403 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
2404 struct timeval timeout,
2406 struct ctdb_tunable *tunables)
2412 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
2413 &outdata, &res, &timeout, NULL);
2414 if (ret != 0 || res != 0) {
2415 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
2419 if (outdata.dsize != sizeof(*tunables)) {
2420 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
2421 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
2425 *tunables = *(struct ctdb_tunable *)outdata.dptr;
2426 talloc_free(outdata.dptr);
2431 add a public address to a node
2433 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
2434 struct timeval timeout,
2436 struct ctdb_control_ip_iface *pub)
2442 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2443 data.dptr = (unsigned char *)pub;
2445 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
2446 NULL, &res, &timeout, NULL);
2447 if (ret != 0 || res != 0) {
2448 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
2456 delete a public address from a node
2458 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
2459 struct timeval timeout,
2461 struct ctdb_control_ip_iface *pub)
2467 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2468 data.dptr = (unsigned char *)pub;
2470 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
2471 NULL, &res, &timeout, NULL);
2472 if (ret != 0 || res != 0) {
2473 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
2481 kill a tcp connection
2483 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
2484 struct timeval timeout,
2486 struct ctdb_control_killtcp *killtcp)
2492 data.dsize = sizeof(struct ctdb_control_killtcp);
2493 data.dptr = (unsigned char *)killtcp;
2495 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
2496 NULL, &res, &timeout, NULL);
2497 if (ret != 0 || res != 0) {
2498 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
2508 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
2509 struct timeval timeout,
2511 ctdb_sock_addr *addr,
2517 struct ctdb_control_gratious_arp *gratious_arp;
2518 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2521 len = strlen(ifname)+1;
2522 gratious_arp = talloc_size(tmp_ctx,
2523 offsetof(struct ctdb_control_gratious_arp, iface) + len);
2524 CTDB_NO_MEMORY(ctdb, gratious_arp);
2526 gratious_arp->addr = *addr;
2527 gratious_arp->len = len;
2528 memcpy(&gratious_arp->iface[0], ifname, len);
2531 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
2532 data.dptr = (unsigned char *)gratious_arp;
2534 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
2535 NULL, &res, &timeout, NULL);
2536 if (ret != 0 || res != 0) {
2537 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
2538 talloc_free(tmp_ctx);
2542 talloc_free(tmp_ctx);
2547 get a list of all tcp tickles that a node knows about for a particular vnn
2549 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
2550 struct timeval timeout, uint32_t destnode,
2551 TALLOC_CTX *mem_ctx,
2552 ctdb_sock_addr *addr,
2553 struct ctdb_control_tcp_tickle_list **list)
2556 TDB_DATA data, outdata;
2559 data.dptr = (uint8_t*)addr;
2560 data.dsize = sizeof(ctdb_sock_addr);
2562 ret = ctdb_control(ctdb, destnode, 0,
2563 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
2564 mem_ctx, &outdata, &status, NULL, NULL);
2565 if (ret != 0 || status != 0) {
2566 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
2570 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
2576 register a server id
2578 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
2579 struct timeval timeout,
2580 struct ctdb_server_id *id)
2586 data.dsize = sizeof(struct ctdb_server_id);
2587 data.dptr = (unsigned char *)id;
2589 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2590 CTDB_CONTROL_REGISTER_SERVER_ID,
2592 NULL, &res, &timeout, NULL);
2593 if (ret != 0 || res != 0) {
2594 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
2602 unregister a server id
2604 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
2605 struct timeval timeout,
2606 struct ctdb_server_id *id)
2612 data.dsize = sizeof(struct ctdb_server_id);
2613 data.dptr = (unsigned char *)id;
2615 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2616 CTDB_CONTROL_UNREGISTER_SERVER_ID,
2618 NULL, &res, &timeout, NULL);
2619 if (ret != 0 || res != 0) {
2620 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
2629 check if a server id exists
2631 if a server id does exist, return *status == 1, otherwise *status == 0
2633 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
2634 struct timeval timeout,
2636 struct ctdb_server_id *id,
2643 data.dsize = sizeof(struct ctdb_server_id);
2644 data.dptr = (unsigned char *)id;
2646 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
2648 NULL, &res, &timeout, NULL);
2650 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
2664 get the list of server ids that are registered on a node
2666 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
2667 TALLOC_CTX *mem_ctx,
2668 struct timeval timeout, uint32_t destnode,
2669 struct ctdb_server_id_list **svid_list)
2675 ret = ctdb_control(ctdb, destnode, 0,
2676 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
2677 mem_ctx, &outdata, &res, &timeout, NULL);
2678 if (ret != 0 || res != 0) {
2679 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
2683 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
2689 initialise the ctdb daemon for client applications
2691 NOTE: In current code the daemon does not fork. This is for testing purposes only
2692 and to simplify the code.
2694 struct ctdb_context *ctdb_init(struct event_context *ev)
2697 struct ctdb_context *ctdb;
2699 ctdb = talloc_zero(ev, struct ctdb_context);
2701 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
2705 ctdb->idr = idr_init(ctdb);
2706 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
2708 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
2710 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
2722 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
2724 ctdb->flags |= flags;
2728 setup the local socket name
2730 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
2732 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
2733 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
2739 return the pnn of this node
2741 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
2748 get the uptime of a remote node
2750 struct ctdb_client_control_state *
2751 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
2753 return ctdb_control_send(ctdb, destnode, 0,
2754 CTDB_CONTROL_UPTIME, 0, tdb_null,
2755 mem_ctx, &timeout, NULL);
2758 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
2764 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
2765 if (ret != 0 || res != 0) {
2766 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
2770 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
2775 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
2777 struct ctdb_client_control_state *state;
2779 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
2780 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
2784 send a control to execute the "recovered" event script on a node
2786 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2791 ret = ctdb_control(ctdb, destnode, 0,
2792 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
2793 NULL, NULL, &status, &timeout, NULL);
2794 if (ret != 0 || status != 0) {
2795 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
2803 callback for the async helpers used when sending the same control
2804 to multiple nodes in parallell.
2806 static void async_callback(struct ctdb_client_control_state *state)
2808 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
2809 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
2813 uint32_t destnode = state->c->hdr.destnode;
2815 /* one more node has responded with recmode data */
2818 /* if we failed to push the db, then return an error and let
2819 the main loop try again.
2821 if (state->state != CTDB_CONTROL_DONE) {
2822 if ( !data->dont_log_errors) {
2823 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
2826 if (data->fail_callback) {
2827 data->fail_callback(ctdb, destnode, res, outdata,
2828 data->callback_data);
2833 state->async.fn = NULL;
2835 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
2836 if ((ret != 0) || (res != 0)) {
2837 if ( !data->dont_log_errors) {
2838 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
2841 if (data->fail_callback) {
2842 data->fail_callback(ctdb, destnode, res, outdata,
2843 data->callback_data);
2846 if ((ret == 0) && (data->callback != NULL)) {
2847 data->callback(ctdb, destnode, res, outdata,
2848 data->callback_data);
2853 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
2855 /* set up the callback functions */
2856 state->async.fn = async_callback;
2857 state->async.private_data = data;
2859 /* one more control to wait for to complete */
2864 /* wait for up to the maximum number of seconds allowed
2865 or until all nodes we expect a response from has replied
2867 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
2869 while (data->count > 0) {
2870 event_loop_once(ctdb->ev);
2872 if (data->fail_count != 0) {
2873 if (!data->dont_log_errors) {
2874 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
2884 perform a simple control on the listed nodes
2885 The control cannot return data
2887 int ctdb_client_async_control(struct ctdb_context *ctdb,
2888 enum ctdb_controls opcode,
2891 struct timeval timeout,
2892 bool dont_log_errors,
2894 client_async_callback client_callback,
2895 client_async_callback fail_callback,
2896 void *callback_data)
2898 struct client_async_data *async_data;
2899 struct ctdb_client_control_state *state;
2902 async_data = talloc_zero(ctdb, struct client_async_data);
2903 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
2904 async_data->dont_log_errors = dont_log_errors;
2905 async_data->callback = client_callback;
2906 async_data->fail_callback = fail_callback;
2907 async_data->callback_data = callback_data;
2908 async_data->opcode = opcode;
2910 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
2912 /* loop over all nodes and send an async control to each of them */
2913 for (j=0; j<num_nodes; j++) {
2914 uint32_t pnn = nodes[j];
2916 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
2917 0, data, async_data, &timeout, NULL);
2918 if (state == NULL) {
2919 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
2920 talloc_free(async_data);
2924 ctdb_client_async_add(async_data, state);
2927 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
2928 talloc_free(async_data);
2932 talloc_free(async_data);
2936 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
2937 struct ctdb_vnn_map *vnn_map,
2938 TALLOC_CTX *mem_ctx,
2941 int i, j, num_nodes;
2944 for (i=num_nodes=0;i<vnn_map->size;i++) {
2945 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2951 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2952 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2954 for (i=j=0;i<vnn_map->size;i++) {
2955 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2958 nodes[j++] = vnn_map->map[i];
2964 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
2965 struct ctdb_node_map *node_map,
2966 TALLOC_CTX *mem_ctx,
2969 int i, j, num_nodes;
2972 for (i=num_nodes=0;i<node_map->num;i++) {
2973 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2976 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2982 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2983 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2985 for (i=j=0;i<node_map->num;i++) {
2986 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2989 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2992 nodes[j++] = node_map->nodes[i].pnn;
2998 uint32_t *list_of_active_nodes_except_pnn(struct ctdb_context *ctdb,
2999 struct ctdb_node_map *node_map,
3000 TALLOC_CTX *mem_ctx,
3003 int i, j, num_nodes;
3006 for (i=num_nodes=0;i<node_map->num;i++) {
3007 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3010 if (node_map->nodes[i].pnn == pnn) {
3016 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3017 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3019 for (i=j=0;i<node_map->num;i++) {
3020 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3023 if (node_map->nodes[i].pnn == pnn) {
3026 nodes[j++] = node_map->nodes[i].pnn;
3032 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
3033 struct ctdb_node_map *node_map,
3034 TALLOC_CTX *mem_ctx,
3037 int i, j, num_nodes;
3040 for (i=num_nodes=0;i<node_map->num;i++) {
3041 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3044 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3050 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3051 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3053 for (i=j=0;i<node_map->num;i++) {
3054 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3057 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3060 nodes[j++] = node_map->nodes[i].pnn;
3067 this is used to test if a pnn lock exists and if it exists will return
3068 the number of connections that pnn has reported or -1 if that recovery
3069 daemon is not running.
3072 ctdb_read_pnn_lock(int fd, int32_t pnn)
3077 lock.l_type = F_WRLCK;
3078 lock.l_whence = SEEK_SET;
3083 if (fcntl(fd, F_GETLK, &lock) != 0) {
3084 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3088 if (lock.l_type == F_UNLCK) {
3092 if (pread(fd, &c, 1, pnn) == -1) {
3093 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3101 get capabilities of a remote node
3103 struct ctdb_client_control_state *
3104 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3106 return ctdb_control_send(ctdb, destnode, 0,
3107 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3108 mem_ctx, &timeout, NULL);
3111 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3117 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3118 if ( (ret != 0) || (res != 0) ) {
3119 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3124 *capabilities = *((uint32_t *)outdata.dptr);
3130 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3132 struct ctdb_client_control_state *state;
3133 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3136 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3137 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3138 talloc_free(tmp_ctx);
3142 struct ctdb_transaction_handle {
3143 struct ctdb_db_context *ctdb_db;
3145 /* we store the reads and writes done under a transaction one
3146 list stores both reads and writes, the other just writes
3148 struct ctdb_marshall_buffer *m_all;
3149 struct ctdb_marshall_buffer *m_write;
3152 /* start a transaction on a database */
3153 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
3155 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3159 /* start a transaction on a database */
3160 static int ctdb_transaction_fetch_start(struct ctdb_transaction_handle *h)
3162 struct ctdb_record_handle *rh;
3165 struct ctdb_ltdb_header header;
3166 TALLOC_CTX *tmp_ctx;
3167 const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
3169 struct ctdb_db_context *ctdb_db = h->ctdb_db;
3172 key.dptr = discard_const(keyname);
3173 key.dsize = strlen(keyname);
3175 if (!ctdb_db->persistent) {
3176 DEBUG(DEBUG_ERR,(__location__ " Attempted transaction on non-persistent database\n"));
3181 tmp_ctx = talloc_new(h);
3183 rh = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, NULL);
3185 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch_lock database\n"));
3186 talloc_free(tmp_ctx);
3190 * store the pid in the database:
3191 * it is not enough that the node is dmaster...
3194 data.dptr = (unsigned char *)&pid;
3195 data.dsize = sizeof(pid_t);
3196 ret = ctdb_ltdb_store(ctdb_db, key, &(rh->header), data);
3198 DEBUG(DEBUG_ERR, (__location__ " Failed to store pid in "
3199 "transaction record\n"));
3200 talloc_free(tmp_ctx);
3206 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3208 DEBUG(DEBUG_ERR,(__location__ " Failed to start tdb transaction\n"));
3209 talloc_free(tmp_ctx);
3213 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, &data);
3214 if (ret != 0 || header.dmaster != ctdb_db->ctdb->pnn) {
3215 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3216 talloc_free(tmp_ctx);
3220 if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
3221 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3222 talloc_free(tmp_ctx);
3226 talloc_free(tmp_ctx);
3232 /* start a transaction on a database */
3233 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
3234 TALLOC_CTX *mem_ctx)
3236 struct ctdb_transaction_handle *h;
3239 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
3241 DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
3245 h->ctdb_db = ctdb_db;
3247 ret = ctdb_transaction_fetch_start(h);
3253 talloc_set_destructor(h, ctdb_transaction_destructor);
3261 fetch a record inside a transaction
3263 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
3264 TALLOC_CTX *mem_ctx,
3265 TDB_DATA key, TDB_DATA *data)
3267 struct ctdb_ltdb_header header;
3270 ZERO_STRUCT(header);
3272 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
3273 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3274 /* record doesn't exist yet */
3283 if (!h->in_replay) {
3284 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
3285 if (h->m_all == NULL) {
3286 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3295 stores a record inside a transaction
3297 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
3298 TDB_DATA key, TDB_DATA data)
3300 TALLOC_CTX *tmp_ctx = talloc_new(h);
3301 struct ctdb_ltdb_header header;
3305 ZERO_STRUCT(header);
3307 /* we need the header so we can update the RSN */
3308 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
3309 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3310 /* the record doesn't exist - create one with us as dmaster.
3311 This is only safe because we are in a transaction and this
3312 is a persistent database */
3313 ZERO_STRUCT(header);
3314 } else if (ret != 0) {
3315 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
3316 talloc_free(tmp_ctx);
3320 if (data.dsize == olddata.dsize &&
3321 memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
3322 /* save writing the same data */
3323 talloc_free(tmp_ctx);
3327 header.dmaster = h->ctdb_db->ctdb->pnn;
3330 if (!h->in_replay) {
3331 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
3332 if (h->m_all == NULL) {
3333 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3334 talloc_free(tmp_ctx);
3339 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
3340 if (h->m_write == NULL) {
3341 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3342 talloc_free(tmp_ctx);
3346 ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
3348 talloc_free(tmp_ctx);
3354 replay a transaction
3356 static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
3359 struct ctdb_rec_data *rec = NULL;
3361 h->in_replay = true;
3362 talloc_free(h->m_write);
3365 ret = ctdb_transaction_fetch_start(h);
3370 for (i=0;i<h->m_all->count;i++) {
3373 rec = ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
3375 DEBUG(DEBUG_ERR, (__location__ " Out of records in ctdb_replay_transaction?\n"));
3379 if (rec->reqid == 0) {
3381 if (ctdb_transaction_store(h, key, data) != 0) {
3386 TALLOC_CTX *tmp_ctx = talloc_new(h);
3388 if (ctdb_transaction_fetch(h, tmp_ctx, key, &data2) != 0) {
3389 talloc_free(tmp_ctx);
3392 if (data2.dsize != data.dsize ||
3393 memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
3394 /* the record has changed on us - we have to give up */
3395 talloc_free(tmp_ctx);
3398 talloc_free(tmp_ctx);
3405 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3411 commit a transaction
3413 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
3417 struct ctdb_context *ctdb = h->ctdb_db->ctdb;
3418 struct timeval timeout;
3419 enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
3421 talloc_set_destructor(h, NULL);
3423 /* our commit strategy is quite complex.
3425 - we first try to commit the changes to all other nodes
3427 - if that works, then we commit locally and we are done
3429 - if a commit on another node fails, then we need to cancel
3430 the transaction, then restart the transaction (thus
3431 opening a window of time for a pending recovery to
3432 complete), then replay the transaction, checking all the
3433 reads and writes (checking that reads give the same data,
3434 and writes succeed). Then we retry the transaction to the
3439 if (h->m_write == NULL) {
3440 /* no changes were made */
3441 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3446 /* tell ctdbd to commit to the other nodes */
3447 timeout = timeval_current_ofs(1, 0);
3448 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3449 retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY, 0,
3450 ctdb_marshall_finish(h->m_write), NULL, NULL, &status,
3452 if (ret != 0 || status != 0) {
3453 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3457 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3459 /* work out what error code we will give if we
3460 have to fail the operation */
3461 switch ((enum ctdb_trans2_commit_error)status) {
3462 case CTDB_TRANS2_COMMIT_SUCCESS:
3463 case CTDB_TRANS2_COMMIT_SOMEFAIL:
3464 case CTDB_TRANS2_COMMIT_TIMEOUT:
3465 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3467 case CTDB_TRANS2_COMMIT_ALLFAIL:
3468 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
3473 if (++retries == 10) {
3474 DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
3475 h->ctdb_db->db_id, retries, (unsigned)failure_control));
3476 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3477 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3478 tdb_null, NULL, NULL, NULL, NULL, NULL);
3483 if (ctdb_replay_transaction(h) != 0) {
3484 DEBUG(DEBUG_ERR,(__location__ " Failed to replay transaction\n"));
3485 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3486 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3487 tdb_null, NULL, NULL, NULL, NULL, NULL);
3493 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3496 /* do the real commit locally */
3497 ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
3499 DEBUG(DEBUG_ERR,(__location__ " Failed to commit transaction\n"));
3500 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3501 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3502 tdb_null, NULL, NULL, NULL, NULL, NULL);
3507 /* tell ctdbd that we are finished with our local commit */
3508 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3509 CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
3510 tdb_null, NULL, NULL, NULL, NULL, NULL);
3516 recovery daemon ping to main daemon
3518 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
3523 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
3524 ctdb, NULL, &res, NULL, NULL);
3525 if (ret != 0 || res != 0) {
3526 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
3533 /* when forking the main daemon and the child process needs to connect back
3534 * to the daemon as a client process, this function can be used to change
3535 * the ctdb context from daemon into client mode
3537 int switch_from_server_to_client(struct ctdb_context *ctdb)
3541 /* shutdown the transport */
3542 if (ctdb->methods) {
3543 ctdb->methods->shutdown(ctdb);
3546 /* get a new event context */
3547 talloc_free(ctdb->ev);
3548 ctdb->ev = event_context_init(ctdb);
3550 close(ctdb->daemon.sd);
3551 ctdb->daemon.sd = -1;
3553 /* the client does not need to be realtime */
3554 if (ctdb->do_setsched) {
3555 ctdb_restore_scheduler(ctdb);
3558 /* initialise ctdb */
3559 ret = ctdb_socket_connect(ctdb);
3561 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
3569 tell the main daemon we are starting a new monitor event script
3571 int ctdb_ctrl_event_script_init(struct ctdb_context *ctdb)
3576 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_INIT, 0, tdb_null,
3577 ctdb, NULL, &res, NULL, NULL);
3578 if (ret != 0 || res != 0) {
3579 DEBUG(DEBUG_ERR,("Failed to send event_script_init\n"));
3587 tell the main daemon we are starting a new monitor event script
3589 int ctdb_ctrl_event_script_finished(struct ctdb_context *ctdb)
3594 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_FINISHED, 0, tdb_null,
3595 ctdb, NULL, &res, NULL, NULL);
3596 if (ret != 0 || res != 0) {
3597 DEBUG(DEBUG_ERR,("Failed to send event_script_init\n"));
3605 tell the main daemon we are starting to run an eventscript
3607 int ctdb_ctrl_event_script_start(struct ctdb_context *ctdb, const char *name)
3613 data.dptr = discard_const(name);
3614 data.dsize = strlen(name)+1;
3616 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_START, 0, data,
3617 ctdb, NULL, &res, NULL, NULL);
3618 if (ret != 0 || res != 0) {
3619 DEBUG(DEBUG_ERR,("Failed to send event_script_start\n"));
3627 tell the main daemon the status of the script we ran
3629 int ctdb_ctrl_event_script_stop(struct ctdb_context *ctdb, int32_t result)
3635 data.dptr = (uint8_t *)&result;
3636 data.dsize = sizeof(result);
3638 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_STOP, 0, data,
3639 ctdb, NULL, &res, NULL, NULL);
3640 if (ret != 0 || res != 0) {
3641 DEBUG(DEBUG_ERR,("Failed to send event_script_stop\n"));
3649 tell the main daemon a script was disabled
3651 int ctdb_ctrl_event_script_disabled(struct ctdb_context *ctdb, const char *name)
3657 data.dptr = discard_const(name);
3658 data.dsize = strlen(name)+1;
3660 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_DISABLED, 0, data,
3661 ctdb, NULL, &res, NULL, NULL);
3662 if (ret != 0 || res != 0) {
3663 DEBUG(DEBUG_ERR,("Failed to send event_script_disabeld\n"));
3671 get the status of running the monitor eventscripts
3673 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
3674 struct timeval timeout, uint32_t destnode,
3675 TALLOC_CTX *mem_ctx,
3676 struct ctdb_monitoring_wire **script_status)
3682 ret = ctdb_control(ctdb, destnode, 0,
3683 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, tdb_null,
3684 mem_ctx, &outdata, &res, &timeout, NULL);
3685 if (ret != 0 || res != 0 || outdata.dsize == 0) {
3686 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
3690 *script_status = (struct ctdb_monitoring_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
3691 talloc_free(outdata.dptr);
3697 tell the main daemon how long it took to lock the reclock file
3699 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
3705 data.dptr = (uint8_t *)&latency;
3706 data.dsize = sizeof(latency);
3708 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
3709 ctdb, NULL, &res, NULL, NULL);
3710 if (ret != 0 || res != 0) {
3711 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
3719 get the name of the reclock file
3721 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
3722 uint32_t destnode, TALLOC_CTX *mem_ctx,
3729 ret = ctdb_control(ctdb, destnode, 0,
3730 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
3731 mem_ctx, &data, &res, &timeout, NULL);
3732 if (ret != 0 || res != 0) {
3736 if (data.dsize == 0) {
3739 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
3741 talloc_free(data.dptr);
3747 set the reclock filename for a node
3749 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
3755 if (reclock == NULL) {
3759 data.dsize = strlen(reclock) + 1;
3760 data.dptr = discard_const(reclock);
3763 ret = ctdb_control(ctdb, destnode, 0,
3764 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
3765 NULL, NULL, &res, &timeout, NULL);
3766 if (ret != 0 || res != 0) {
3767 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
3777 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3782 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
3783 ctdb, NULL, &res, &timeout, NULL);
3784 if (ret != 0 || res != 0) {
3785 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
3795 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3799 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
3800 ctdb, NULL, NULL, &timeout, NULL);
3802 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
3810 set the natgw state for a node
3812 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
3818 data.dsize = sizeof(natgwstate);
3819 data.dptr = (uint8_t *)&natgwstate;
3821 ret = ctdb_control(ctdb, destnode, 0,
3822 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
3823 NULL, NULL, &res, &timeout, NULL);
3824 if (ret != 0 || res != 0) {
3825 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
3833 set the lmaster role for a node
3835 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
3841 data.dsize = sizeof(lmasterrole);
3842 data.dptr = (uint8_t *)&lmasterrole;
3844 ret = ctdb_control(ctdb, destnode, 0,
3845 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
3846 NULL, NULL, &res, &timeout, NULL);
3847 if (ret != 0 || res != 0) {
3848 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
3856 set the recmaster role for a node
3858 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
3864 data.dsize = sizeof(recmasterrole);
3865 data.dptr = (uint8_t *)&recmasterrole;
3867 ret = ctdb_control(ctdb, destnode, 0,
3868 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
3869 NULL, NULL, &res, &timeout, NULL);
3870 if (ret != 0 || res != 0) {
3871 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
3878 /* enable an eventscript
3880 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
3886 data.dsize = strlen(script) + 1;
3887 data.dptr = discard_const(script);
3889 ret = ctdb_control(ctdb, destnode, 0,
3890 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
3891 NULL, NULL, &res, &timeout, NULL);
3892 if (ret != 0 || res != 0) {
3893 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
3900 /* disable an eventscript
3902 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
3908 data.dsize = strlen(script) + 1;
3909 data.dptr = discard_const(script);
3911 ret = ctdb_control(ctdb, destnode, 0,
3912 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
3913 NULL, NULL, &res, &timeout, NULL);
3914 if (ret != 0 || res != 0) {
3915 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
3923 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime)
3929 data.dsize = sizeof(*bantime);
3930 data.dptr = (uint8_t *)bantime;
3932 ret = ctdb_control(ctdb, destnode, 0,
3933 CTDB_CONTROL_SET_BAN_STATE, 0, data,
3934 NULL, NULL, &res, &timeout, NULL);
3935 if (ret != 0 || res != 0) {
3936 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
3944 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime)
3949 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3951 ret = ctdb_control(ctdb, destnode, 0,
3952 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
3953 tmp_ctx, &outdata, &res, &timeout, NULL);
3954 if (ret != 0 || res != 0) {
3955 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
3956 talloc_free(tmp_ctx);
3960 *bantime = (struct ctdb_ban_time *)talloc_steal(mem_ctx, outdata.dptr);
3961 talloc_free(tmp_ctx);
3967 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
3972 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3974 data.dptr = (uint8_t*)db_prio;
3975 data.dsize = sizeof(*db_prio);
3977 ret = ctdb_control(ctdb, destnode, 0,
3978 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
3979 tmp_ctx, NULL, &res, &timeout, NULL);
3980 if (ret != 0 || res != 0) {
3981 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
3982 talloc_free(tmp_ctx);
3986 talloc_free(tmp_ctx);
3991 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
3996 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3998 data.dptr = (uint8_t*)&db_id;
3999 data.dsize = sizeof(db_id);
4001 ret = ctdb_control(ctdb, destnode, 0,
4002 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
4003 tmp_ctx, NULL, &res, &timeout, NULL);
4004 if (ret != 0 || res < 0) {
4005 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4006 talloc_free(tmp_ctx);
4014 talloc_free(tmp_ctx);