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"
36 allocate a packet for use in client<->daemon communication
38 struct ctdb_req_header *_ctdbd_allocate_pkt(struct ctdb_context *ctdb,
40 enum ctdb_operation operation,
41 size_t length, size_t slength,
45 struct ctdb_req_header *hdr;
47 length = MAX(length, slength);
48 size = (length+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
50 hdr = (struct ctdb_req_header *)talloc_size(mem_ctx, size);
52 DEBUG(DEBUG_ERR,("Unable to allocate packet for operation %u of length %u\n",
53 operation, (unsigned)length));
56 talloc_set_name_const(hdr, type);
57 memset(hdr, 0, slength);
59 hdr->operation = operation;
60 hdr->ctdb_magic = CTDB_MAGIC;
61 hdr->ctdb_version = CTDB_VERSION;
62 hdr->srcnode = ctdb->pnn;
64 hdr->generation = ctdb->vnn_map->generation;
71 local version of ctdb_call
73 int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
74 struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx,
75 TDB_DATA *data, uint32_t caller)
77 struct ctdb_call_info *c;
78 struct ctdb_registered_call *fn;
79 struct ctdb_context *ctdb = ctdb_db->ctdb;
81 c = talloc(ctdb, struct ctdb_call_info);
82 CTDB_NO_MEMORY(ctdb, c);
85 c->call_data = &call->call_data;
86 c->record_data.dptr = talloc_memdup(c, data->dptr, data->dsize);
87 c->record_data.dsize = data->dsize;
88 CTDB_NO_MEMORY(ctdb, c->record_data.dptr);
93 for (fn=ctdb_db->calls;fn;fn=fn->next) {
94 if (fn->id == call->call_id) break;
97 ctdb_set_error(ctdb, "Unknown call id %u\n", call->call_id);
102 if (fn->fn(c) != 0) {
103 ctdb_set_error(ctdb, "ctdb_call %u failed\n", call->call_id);
108 if (header->laccessor != caller) {
111 header->laccessor = caller;
114 /* we need to force the record to be written out if this was a remote access,
115 so that the lacount is updated */
116 if (c->new_data == NULL && header->laccessor != ctdb->pnn) {
117 c->new_data = &c->record_data;
121 /* XXX check that we always have the lock here? */
122 if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
123 ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
130 call->reply_data = *c->reply_data;
132 talloc_steal(call, call->reply_data.dptr);
133 talloc_set_name_const(call->reply_data.dptr, __location__);
135 call->reply_data.dptr = NULL;
136 call->reply_data.dsize = 0;
138 call->status = c->status;
147 queue a packet for sending from client to daemon
149 static int ctdb_client_queue_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
151 return ctdb_queue_send(ctdb->daemon.queue, (uint8_t *)hdr, hdr->length);
156 called when a CTDB_REPLY_CALL packet comes in in the client
158 This packet comes in response to a CTDB_REQ_CALL request packet. It
159 contains any reply data from the call
161 static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
163 struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
164 struct ctdb_client_call_state *state;
166 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_call_state);
168 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
172 if (hdr->reqid != state->reqid) {
173 /* we found a record but it was the wrong one */
174 DEBUG(DEBUG_ERR, ("Dropped client call reply with reqid:%u\n",hdr->reqid));
178 state->call->reply_data.dptr = c->data;
179 state->call->reply_data.dsize = c->datalen;
180 state->call->status = c->status;
182 talloc_steal(state, c);
184 state->state = CTDB_CALL_DONE;
186 if (state->async.fn) {
187 state->async.fn(state);
191 static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
194 this is called in the client, when data comes in from the daemon
196 static void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
198 struct ctdb_context *ctdb = talloc_get_type(args, struct ctdb_context);
199 struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
202 /* place the packet as a child of a tmp_ctx. We then use
203 talloc_free() below to free it. If any of the calls want
204 to keep it, then they will steal it somewhere else, and the
205 talloc_free() will be a no-op */
206 tmp_ctx = talloc_new(ctdb);
207 talloc_steal(tmp_ctx, hdr);
210 DEBUG(DEBUG_INFO,("Daemon has exited - shutting down client\n"));
214 if (cnt < sizeof(*hdr)) {
215 DEBUG(DEBUG_CRIT,("Bad packet length %u in client\n", (unsigned)cnt));
218 if (cnt != hdr->length) {
219 ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
220 (unsigned)hdr->length, (unsigned)cnt);
224 if (hdr->ctdb_magic != CTDB_MAGIC) {
225 ctdb_set_error(ctdb, "Non CTDB packet rejected in client\n");
229 if (hdr->ctdb_version != CTDB_VERSION) {
230 ctdb_set_error(ctdb, "Bad CTDB version 0x%x rejected in client\n", hdr->ctdb_version);
234 switch (hdr->operation) {
235 case CTDB_REPLY_CALL:
236 ctdb_client_reply_call(ctdb, hdr);
239 case CTDB_REQ_MESSAGE:
240 ctdb_request_message(ctdb, hdr);
243 case CTDB_REPLY_CONTROL:
244 ctdb_client_reply_control(ctdb, hdr);
248 DEBUG(DEBUG_CRIT,("bogus operation code:%u\n",hdr->operation));
252 talloc_free(tmp_ctx);
256 connect to a unix domain socket
258 int ctdb_socket_connect(struct ctdb_context *ctdb)
260 struct sockaddr_un addr;
262 memset(&addr, 0, sizeof(addr));
263 addr.sun_family = AF_UNIX;
264 strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path));
266 ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
267 if (ctdb->daemon.sd == -1) {
268 DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
272 set_nonblocking(ctdb->daemon.sd);
273 set_close_on_exec(ctdb->daemon.sd);
275 if (connect(ctdb->daemon.sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
276 close(ctdb->daemon.sd);
277 ctdb->daemon.sd = -1;
278 DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
282 ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
284 ctdb_client_read_cb, ctdb);
289 struct ctdb_record_handle {
290 struct ctdb_db_context *ctdb_db;
293 struct ctdb_ltdb_header header;
298 make a recv call to the local ctdb daemon - called from client context
300 This is called when the program wants to wait for a ctdb_call to complete and get the
301 results. This call will block unless the call has already completed.
303 int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
309 while (state->state < CTDB_CALL_DONE) {
310 event_loop_once(state->ctdb_db->ctdb->ev);
312 if (state->state != CTDB_CALL_DONE) {
313 DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
318 if (state->call->reply_data.dsize) {
319 call->reply_data.dptr = talloc_memdup(state->ctdb_db,
320 state->call->reply_data.dptr,
321 state->call->reply_data.dsize);
322 call->reply_data.dsize = state->call->reply_data.dsize;
324 call->reply_data.dptr = NULL;
325 call->reply_data.dsize = 0;
327 call->status = state->call->status;
337 destroy a ctdb_call in client
339 static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
341 ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
346 construct an event driven local ctdb_call
348 this is used so that locally processed ctdb_call requests are processed
349 in an event driven manner
351 static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
352 struct ctdb_call *call,
353 struct ctdb_ltdb_header *header,
356 struct ctdb_client_call_state *state;
357 struct ctdb_context *ctdb = ctdb_db->ctdb;
360 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
361 CTDB_NO_MEMORY_NULL(ctdb, state);
362 state->call = talloc_zero(state, struct ctdb_call);
363 CTDB_NO_MEMORY_NULL(ctdb, state->call);
365 talloc_steal(state, data->dptr);
367 state->state = CTDB_CALL_DONE;
368 *(state->call) = *call;
369 state->ctdb_db = ctdb_db;
371 ret = ctdb_call_local(ctdb_db, state->call, header, state, data, ctdb->pnn);
377 make a ctdb call to the local daemon - async send. Called from client context.
379 This constructs a ctdb_call request and queues it for processing.
380 This call never blocks.
382 struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
383 struct ctdb_call *call)
385 struct ctdb_client_call_state *state;
386 struct ctdb_context *ctdb = ctdb_db->ctdb;
387 struct ctdb_ltdb_header header;
391 struct ctdb_req_call *c;
393 /* if the domain socket is not yet open, open it */
394 if (ctdb->daemon.sd==-1) {
395 ctdb_socket_connect(ctdb);
398 ret = ctdb_ltdb_lock(ctdb_db, call->key);
400 DEBUG(DEBUG_ERR,(__location__ " Failed to get chainlock\n"));
404 ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
406 if (ret == 0 && header.dmaster == ctdb->pnn) {
407 state = ctdb_client_call_local_send(ctdb_db, call, &header, &data);
408 talloc_free(data.dptr);
409 ctdb_ltdb_unlock(ctdb_db, call->key);
413 ctdb_ltdb_unlock(ctdb_db, call->key);
414 talloc_free(data.dptr);
416 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
418 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state\n"));
421 state->call = talloc_zero(state, struct ctdb_call);
422 if (state->call == NULL) {
423 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state->call\n"));
427 len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
428 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CALL, len, struct ctdb_req_call);
430 DEBUG(DEBUG_ERR, (__location__ " failed to allocate packet\n"));
434 state->reqid = ctdb_reqid_new(ctdb, state);
435 state->ctdb_db = ctdb_db;
436 talloc_set_destructor(state, ctdb_client_call_destructor);
438 c->hdr.reqid = state->reqid;
439 c->flags = call->flags;
440 c->db_id = ctdb_db->db_id;
441 c->callid = call->call_id;
443 c->keylen = call->key.dsize;
444 c->calldatalen = call->call_data.dsize;
445 memcpy(&c->data[0], call->key.dptr, call->key.dsize);
446 memcpy(&c->data[call->key.dsize],
447 call->call_data.dptr, call->call_data.dsize);
448 *(state->call) = *call;
449 state->call->call_data.dptr = &c->data[call->key.dsize];
450 state->call->key.dptr = &c->data[0];
452 state->state = CTDB_CALL_WAIT;
455 ctdb_client_queue_pkt(ctdb, &c->hdr);
462 full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
464 int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
466 struct ctdb_client_call_state *state;
468 state = ctdb_call_send(ctdb_db, call);
469 return ctdb_call_recv(state, call);
474 tell the daemon what messaging srvid we will use, and register the message
475 handler function in the client
477 int ctdb_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid,
478 ctdb_message_fn_t handler,
485 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_REGISTER_SRVID, 0,
486 tdb_null, NULL, NULL, &status, NULL, NULL);
487 if (res != 0 || status != 0) {
488 DEBUG(DEBUG_ERR,("Failed to register srvid %llu\n", (unsigned long long)srvid));
492 /* also need to register the handler with our own ctdb structure */
493 return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
497 tell the daemon we no longer want a srvid
499 int ctdb_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid, void *private_data)
504 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_DEREGISTER_SRVID, 0,
505 tdb_null, NULL, NULL, &status, NULL, NULL);
506 if (res != 0 || status != 0) {
507 DEBUG(DEBUG_ERR,("Failed to deregister srvid %llu\n", (unsigned long long)srvid));
511 /* also need to register the handler with our own ctdb structure */
512 ctdb_deregister_message_handler(ctdb, srvid, private_data);
518 send a message - from client context
520 int ctdb_send_message(struct ctdb_context *ctdb, uint32_t pnn,
521 uint64_t srvid, TDB_DATA data)
523 struct ctdb_req_message *r;
526 len = offsetof(struct ctdb_req_message, data) + data.dsize;
527 r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
528 len, struct ctdb_req_message);
529 CTDB_NO_MEMORY(ctdb, r);
531 r->hdr.destnode = pnn;
533 r->datalen = data.dsize;
534 memcpy(&r->data[0], data.dptr, data.dsize);
536 res = ctdb_client_queue_pkt(ctdb, &r->hdr);
547 cancel a ctdb_fetch_lock operation, releasing the lock
549 static int fetch_lock_destructor(struct ctdb_record_handle *h)
551 ctdb_ltdb_unlock(h->ctdb_db, h->key);
556 force the migration of a record to this node
558 static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
560 struct ctdb_call call;
562 call.call_id = CTDB_NULL_FUNC;
564 call.flags = CTDB_IMMEDIATE_MIGRATION;
565 return ctdb_call(ctdb_db, &call);
569 get a lock on a record, and return the records data. Blocks until it gets the lock
571 struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
572 TDB_DATA key, TDB_DATA *data)
575 struct ctdb_record_handle *h;
578 procedure is as follows:
580 1) get the chain lock.
581 2) check if we are dmaster
582 3) if we are the dmaster then return handle
583 4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
585 5) when we get the reply, goto (1)
588 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
593 h->ctdb_db = ctdb_db;
595 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
596 if (h->key.dptr == NULL) {
602 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize,
603 (const char *)key.dptr));
606 /* step 1 - get the chain lock */
607 ret = ctdb_ltdb_lock(ctdb_db, key);
609 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
614 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
616 talloc_set_destructor(h, fetch_lock_destructor);
618 ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
620 /* when torturing, ensure we test the remote path */
621 if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
623 h->header.dmaster = (uint32_t)-1;
627 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
629 if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
630 ctdb_ltdb_unlock(ctdb_db, key);
631 ret = ctdb_client_force_migration(ctdb_db, key);
633 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
640 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
645 store some data to the record that was locked with ctdb_fetch_lock()
647 int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
649 if (h->ctdb_db->persistent) {
650 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
654 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
658 non-locking fetch of a record
660 int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
661 TDB_DATA key, TDB_DATA *data)
663 struct ctdb_call call;
666 call.call_id = CTDB_FETCH_FUNC;
667 call.call_data.dptr = NULL;
668 call.call_data.dsize = 0;
670 ret = ctdb_call(ctdb_db, &call);
673 *data = call.reply_data;
674 talloc_steal(mem_ctx, data->dptr);
683 called when a control completes or timesout to invoke the callback
684 function the user provided
686 static void invoke_control_callback(struct event_context *ev, struct timed_event *te,
687 struct timeval t, void *private_data)
689 struct ctdb_client_control_state *state;
690 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
693 state = talloc_get_type(private_data, struct ctdb_client_control_state);
694 talloc_steal(tmp_ctx, state);
696 ret = ctdb_control_recv(state->ctdb, state, state,
701 talloc_free(tmp_ctx);
705 called when a CTDB_REPLY_CONTROL packet comes in in the client
707 This packet comes in response to a CTDB_REQ_CONTROL request packet. It
708 contains any reply data from the control
710 static void ctdb_client_reply_control(struct ctdb_context *ctdb,
711 struct ctdb_req_header *hdr)
713 struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
714 struct ctdb_client_control_state *state;
716 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_control_state);
718 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
722 if (hdr->reqid != state->reqid) {
723 /* we found a record but it was the wrong one */
724 DEBUG(DEBUG_ERR, ("Dropped orphaned reply control with reqid:%u\n",hdr->reqid));
728 state->outdata.dptr = c->data;
729 state->outdata.dsize = c->datalen;
730 state->status = c->status;
732 state->errormsg = talloc_strndup(state,
733 (char *)&c->data[c->datalen],
737 /* state->outdata now uses resources from c so we dont want c
738 to just dissappear from under us while state is still alive
740 talloc_steal(state, c);
742 state->state = CTDB_CONTROL_DONE;
744 /* if we had a callback registered for this control, pull the response
745 and call the callback.
747 if (state->async.fn) {
748 event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
754 destroy a ctdb_control in client
756 static int ctdb_control_destructor(struct ctdb_client_control_state *state)
758 ctdb_reqid_remove(state->ctdb, state->reqid);
763 /* time out handler for ctdb_control */
764 static void control_timeout_func(struct event_context *ev, struct timed_event *te,
765 struct timeval t, void *private_data)
767 struct ctdb_client_control_state *state = talloc_get_type(private_data, struct ctdb_client_control_state);
769 DEBUG(DEBUG_ERR,("control timed out. reqid:%d opcode:%d dstnode:%d\n", state->reqid, state->c->opcode, state->c->hdr.destnode));
771 state->state = CTDB_CONTROL_TIMEOUT;
773 /* if we had a callback registered for this control, pull the response
774 and call the callback.
776 if (state->async.fn) {
777 event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
781 /* async version of send control request */
782 struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
783 uint32_t destnode, uint64_t srvid,
784 uint32_t opcode, uint32_t flags, TDB_DATA data,
786 struct timeval *timeout,
789 struct ctdb_client_control_state *state;
791 struct ctdb_req_control *c;
798 /* if the domain socket is not yet open, open it */
799 if (ctdb->daemon.sd==-1) {
800 ctdb_socket_connect(ctdb);
803 state = talloc_zero(mem_ctx, struct ctdb_client_control_state);
804 CTDB_NO_MEMORY_NULL(ctdb, state);
807 state->reqid = ctdb_reqid_new(ctdb, state);
808 state->state = CTDB_CONTROL_WAIT;
809 state->errormsg = NULL;
811 talloc_set_destructor(state, ctdb_control_destructor);
813 len = offsetof(struct ctdb_req_control, data) + data.dsize;
814 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
815 len, struct ctdb_req_control);
817 CTDB_NO_MEMORY_NULL(ctdb, c);
818 c->hdr.reqid = state->reqid;
819 c->hdr.destnode = destnode;
824 c->datalen = data.dsize;
826 memcpy(&c->data[0], data.dptr, data.dsize);
830 if (timeout && !timeval_is_zero(timeout)) {
831 event_add_timed(ctdb->ev, state, *timeout, control_timeout_func, state);
834 ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
840 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
849 /* async version of receive control reply */
850 int ctdb_control_recv(struct ctdb_context *ctdb,
851 struct ctdb_client_control_state *state,
853 TDB_DATA *outdata, int32_t *status, char **errormsg)
857 if (status != NULL) {
860 if (errormsg != NULL) {
868 /* prevent double free of state */
869 tmp_ctx = talloc_new(ctdb);
870 talloc_steal(tmp_ctx, state);
872 /* loop one event at a time until we either timeout or the control
875 while (state->state == CTDB_CONTROL_WAIT) {
876 event_loop_once(ctdb->ev);
879 if (state->state != CTDB_CONTROL_DONE) {
880 DEBUG(DEBUG_ERR,(__location__ " ctdb_control_recv failed\n"));
881 if (state->async.fn) {
882 state->async.fn(state);
884 talloc_free(tmp_ctx);
888 if (state->errormsg) {
889 DEBUG(DEBUG_ERR,("ctdb_control error: '%s'\n", state->errormsg));
891 (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
893 if (state->async.fn) {
894 state->async.fn(state);
896 talloc_free(tmp_ctx);
901 *outdata = state->outdata;
902 outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
906 *status = state->status;
909 if (state->async.fn) {
910 state->async.fn(state);
913 talloc_free(tmp_ctx);
920 send a ctdb control message
921 timeout specifies how long we should wait for a reply.
922 if timeout is NULL we wait indefinitely
924 int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
925 uint32_t opcode, uint32_t flags, TDB_DATA data,
926 TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
927 struct timeval *timeout,
930 struct ctdb_client_control_state *state;
932 state = ctdb_control_send(ctdb, destnode, srvid, opcode,
933 flags, data, mem_ctx,
935 return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
943 a process exists call. Returns 0 if process exists, -1 otherwise
945 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
951 data.dptr = (uint8_t*)&pid;
952 data.dsize = sizeof(pid);
954 ret = ctdb_control(ctdb, destnode, 0,
955 CTDB_CONTROL_PROCESS_EXISTS, 0, data,
956 NULL, NULL, &status, NULL, NULL);
958 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
966 get remote statistics
968 int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
974 ret = ctdb_control(ctdb, destnode, 0,
975 CTDB_CONTROL_STATISTICS, 0, tdb_null,
976 ctdb, &data, &res, NULL, NULL);
977 if (ret != 0 || res != 0) {
978 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
982 if (data.dsize != sizeof(struct ctdb_statistics)) {
983 DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
984 (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
988 *status = *(struct ctdb_statistics *)data.dptr;
989 talloc_free(data.dptr);
995 shutdown a remote ctdb node
997 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
999 struct ctdb_client_control_state *state;
1001 state = ctdb_control_send(ctdb, destnode, 0,
1002 CTDB_CONTROL_SHUTDOWN, 0, tdb_null,
1003 NULL, &timeout, NULL);
1004 if (state == NULL) {
1005 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
1013 get vnn map from a remote node
1015 int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
1020 struct ctdb_vnn_map_wire *map;
1022 ret = ctdb_control(ctdb, destnode, 0,
1023 CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
1024 mem_ctx, &outdata, &res, &timeout, NULL);
1025 if (ret != 0 || res != 0) {
1026 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
1030 map = (struct ctdb_vnn_map_wire *)outdata.dptr;
1031 if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
1032 outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
1033 DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
1037 (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
1038 CTDB_NO_MEMORY(ctdb, *vnnmap);
1039 (*vnnmap)->generation = map->generation;
1040 (*vnnmap)->size = map->size;
1041 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
1043 CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
1044 memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
1045 talloc_free(outdata.dptr);
1052 get the recovery mode of a remote node
1054 struct ctdb_client_control_state *
1055 ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
1057 return ctdb_control_send(ctdb, destnode, 0,
1058 CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
1059 mem_ctx, &timeout, NULL);
1062 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
1067 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1069 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
1074 *recmode = (uint32_t)res;
1080 int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
1082 struct ctdb_client_control_state *state;
1084 state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
1085 return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
1092 set the recovery mode of a remote node
1094 int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
1100 data.dsize = sizeof(uint32_t);
1101 data.dptr = (unsigned char *)&recmode;
1103 ret = ctdb_control(ctdb, destnode, 0,
1104 CTDB_CONTROL_SET_RECMODE, 0, data,
1105 NULL, NULL, &res, &timeout, NULL);
1106 if (ret != 0 || res != 0) {
1107 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
1117 get the recovery master of a remote node
1119 struct ctdb_client_control_state *
1120 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
1121 struct timeval timeout, uint32_t destnode)
1123 return ctdb_control_send(ctdb, destnode, 0,
1124 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
1125 mem_ctx, &timeout, NULL);
1128 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
1133 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1135 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
1140 *recmaster = (uint32_t)res;
1146 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
1148 struct ctdb_client_control_state *state;
1150 state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
1151 return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
1156 set the recovery master of a remote node
1158 int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
1165 data.dsize = sizeof(uint32_t);
1166 data.dptr = (unsigned char *)&recmaster;
1168 ret = ctdb_control(ctdb, destnode, 0,
1169 CTDB_CONTROL_SET_RECMASTER, 0, data,
1170 NULL, NULL, &res, &timeout, NULL);
1171 if (ret != 0 || res != 0) {
1172 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
1181 get a list of databases off a remote node
1183 int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1184 TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
1190 ret = ctdb_control(ctdb, destnode, 0,
1191 CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
1192 mem_ctx, &outdata, &res, &timeout, NULL);
1193 if (ret != 0 || res != 0) {
1194 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
1198 *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1199 talloc_free(outdata.dptr);
1205 get a list of nodes (vnn and flags ) from a remote node
1207 int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
1208 struct timeval timeout, uint32_t destnode,
1209 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1215 ret = ctdb_control(ctdb, destnode, 0,
1216 CTDB_CONTROL_GET_NODEMAP, 0, tdb_null,
1217 mem_ctx, &outdata, &res, &timeout, NULL);
1218 if (ret == 0 && res == -1 && outdata.dsize == 0) {
1219 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
1220 return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
1222 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1223 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
1227 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1228 talloc_free(outdata.dptr);
1234 old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
1236 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb,
1237 struct timeval timeout, uint32_t destnode,
1238 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1242 struct ctdb_node_mapv4 *nodemapv4;
1245 ret = ctdb_control(ctdb, destnode, 0,
1246 CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null,
1247 mem_ctx, &outdata, &res, &timeout, NULL);
1248 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1249 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
1253 nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
1255 len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
1256 (*nodemap) = talloc_zero_size(mem_ctx, len);
1257 CTDB_NO_MEMORY(ctdb, (*nodemap));
1259 (*nodemap)->num = nodemapv4->num;
1260 for (i=0; i<nodemapv4->num; i++) {
1261 (*nodemap)->nodes[i].pnn = nodemapv4->nodes[i].pnn;
1262 (*nodemap)->nodes[i].flags = nodemapv4->nodes[i].flags;
1263 (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
1264 (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
1267 talloc_free(outdata.dptr);
1273 drop the transport, reload the nodes file and restart the transport
1275 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
1276 struct timeval timeout, uint32_t destnode)
1281 ret = ctdb_control(ctdb, destnode, 0,
1282 CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
1283 NULL, NULL, &res, &timeout, NULL);
1284 if (ret != 0 || res != 0) {
1285 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
1294 set vnn map on a node
1296 int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1297 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
1302 struct ctdb_vnn_map_wire *map;
1305 len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
1306 map = talloc_size(mem_ctx, len);
1307 CTDB_NO_MEMORY(ctdb, map);
1309 map->generation = vnnmap->generation;
1310 map->size = vnnmap->size;
1311 memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
1314 data.dptr = (uint8_t *)map;
1316 ret = ctdb_control(ctdb, destnode, 0,
1317 CTDB_CONTROL_SETVNNMAP, 0, data,
1318 NULL, NULL, &res, &timeout, NULL);
1319 if (ret != 0 || res != 0) {
1320 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
1331 async send for pull database
1333 struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
1334 struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
1335 uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
1338 struct ctdb_control_pulldb *pull;
1339 struct ctdb_client_control_state *state;
1341 pull = talloc(mem_ctx, struct ctdb_control_pulldb);
1342 CTDB_NO_MEMORY_NULL(ctdb, pull);
1345 pull->lmaster = lmaster;
1347 indata.dsize = sizeof(struct ctdb_control_pulldb);
1348 indata.dptr = (unsigned char *)pull;
1350 state = ctdb_control_send(ctdb, destnode, 0,
1351 CTDB_CONTROL_PULL_DB, 0, indata,
1352 mem_ctx, &timeout, NULL);
1359 async recv for pull database
1361 int ctdb_ctrl_pulldb_recv(
1362 struct ctdb_context *ctdb,
1363 TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state,
1369 ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
1370 if ( (ret != 0) || (res != 0) ){
1371 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
1379 pull all keys and records for a specific database on a node
1381 int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode,
1382 uint32_t dbid, uint32_t lmaster,
1383 TALLOC_CTX *mem_ctx, struct timeval timeout,
1386 struct ctdb_client_control_state *state;
1388 state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
1391 return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
1396 change dmaster for all keys in the database to the new value
1398 int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1399 TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
1405 indata.dsize = 2*sizeof(uint32_t);
1406 indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
1408 ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
1409 ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
1411 ret = ctdb_control(ctdb, destnode, 0,
1412 CTDB_CONTROL_SET_DMASTER, 0, indata,
1413 NULL, NULL, &res, &timeout, NULL);
1414 if (ret != 0 || res != 0) {
1415 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
1423 ping a node, return number of clients connected
1425 int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
1430 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0,
1431 tdb_null, NULL, NULL, &res, NULL, NULL);
1439 find the real path to a ltdb
1441 int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1448 data.dptr = (uint8_t *)&dbid;
1449 data.dsize = sizeof(dbid);
1451 ret = ctdb_control(ctdb, destnode, 0,
1452 CTDB_CONTROL_GETDBPATH, 0, data,
1453 mem_ctx, &data, &res, &timeout, NULL);
1454 if (ret != 0 || res != 0) {
1458 (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1459 if ((*path) == NULL) {
1463 talloc_free(data.dptr);
1469 find the name of a db
1471 int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1478 data.dptr = (uint8_t *)&dbid;
1479 data.dsize = sizeof(dbid);
1481 ret = ctdb_control(ctdb, destnode, 0,
1482 CTDB_CONTROL_GET_DBNAME, 0, data,
1483 mem_ctx, &data, &res, &timeout, NULL);
1484 if (ret != 0 || res != 0) {
1488 (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1489 if ((*name) == NULL) {
1493 talloc_free(data.dptr);
1501 int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1502 TALLOC_CTX *mem_ctx, const char *name, bool persistent)
1508 data.dptr = discard_const(name);
1509 data.dsize = strlen(name)+1;
1511 ret = ctdb_control(ctdb, destnode, 0,
1512 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1514 mem_ctx, &data, &res, &timeout, NULL);
1516 if (ret != 0 || res != 0) {
1524 get debug level on a node
1526 int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
1532 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
1533 ctdb, &data, &res, NULL, NULL);
1534 if (ret != 0 || res != 0) {
1537 if (data.dsize != sizeof(int32_t)) {
1538 DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
1539 (unsigned)data.dsize));
1542 *level = *(int32_t *)data.dptr;
1543 talloc_free(data.dptr);
1548 set debug level on a node
1550 int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
1556 data.dptr = (uint8_t *)&level;
1557 data.dsize = sizeof(level);
1559 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data,
1560 NULL, NULL, &res, NULL, NULL);
1561 if (ret != 0 || res != 0) {
1569 get a list of connected nodes
1571 uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
1572 struct timeval timeout,
1573 TALLOC_CTX *mem_ctx,
1574 uint32_t *num_nodes)
1576 struct ctdb_node_map *map=NULL;
1582 ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
1587 nodes = talloc_array(mem_ctx, uint32_t, map->num);
1588 if (nodes == NULL) {
1592 for (i=0;i<map->num;i++) {
1593 if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
1594 nodes[*num_nodes] = map->nodes[i].pnn;
1606 int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
1611 ret = ctdb_control(ctdb, destnode, 0,
1612 CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null,
1613 NULL, NULL, &res, NULL, NULL);
1614 if (ret != 0 || res != 0) {
1615 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
1622 this is the dummy null procedure that all databases support
1624 static int ctdb_null_func(struct ctdb_call_info *call)
1630 this is a plain fetch procedure that all databases support
1632 static int ctdb_fetch_func(struct ctdb_call_info *call)
1634 call->reply_data = &call->record_data;
1639 attach to a specific database - client call
1641 struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name, bool persistent, uint32_t tdb_flags)
1643 struct ctdb_db_context *ctdb_db;
1648 ctdb_db = ctdb_db_handle(ctdb, name);
1653 ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
1654 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
1656 ctdb_db->ctdb = ctdb;
1657 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
1658 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
1660 data.dptr = discard_const(name);
1661 data.dsize = strlen(name)+1;
1663 /* tell ctdb daemon to attach */
1664 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags,
1665 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1666 0, data, ctdb_db, &data, &res, NULL, NULL);
1667 if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
1668 DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
1669 talloc_free(ctdb_db);
1673 ctdb_db->db_id = *(uint32_t *)data.dptr;
1674 talloc_free(data.dptr);
1676 ret = ctdb_ctrl_getdbpath(ctdb, timeval_current_ofs(2, 0), CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
1678 DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
1679 talloc_free(ctdb_db);
1683 tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
1684 if (!ctdb->do_setsched) {
1685 tdb_flags |= TDB_NOMMAP;
1688 ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
1689 if (ctdb_db->ltdb == NULL) {
1690 ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
1691 talloc_free(ctdb_db);
1695 ctdb_db->persistent = persistent;
1697 DLIST_ADD(ctdb->db_list, ctdb_db);
1699 /* add well known functions */
1700 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
1701 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
1708 setup a call for a database
1710 int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
1712 struct ctdb_registered_call *call;
1717 struct ctdb_control_set_call c;
1720 /* this is no longer valid with the separate daemon architecture */
1721 c.db_id = ctdb_db->db_id;
1725 data.dptr = (uint8_t *)&c;
1726 data.dsize = sizeof(c);
1728 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_SET_CALL, 0,
1729 data, NULL, NULL, &status, NULL, NULL);
1730 if (ret != 0 || status != 0) {
1731 DEBUG(DEBUG_ERR,("ctdb_set_call failed for call %u\n", id));
1736 /* also register locally */
1737 call = talloc(ctdb_db, struct ctdb_registered_call);
1741 DLIST_ADD(ctdb_db->calls, call);
1746 struct traverse_state {
1749 ctdb_traverse_func fn;
1754 called on each key during a ctdb_traverse
1756 static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p)
1758 struct traverse_state *state = (struct traverse_state *)p;
1759 struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
1762 if (data.dsize < sizeof(uint32_t) ||
1763 d->length != data.dsize) {
1764 DEBUG(DEBUG_ERR,("Bad data size %u in traverse_handler\n", (unsigned)data.dsize));
1769 key.dsize = d->keylen;
1770 key.dptr = &d->data[0];
1771 data.dsize = d->datalen;
1772 data.dptr = &d->data[d->keylen];
1774 if (key.dsize == 0 && data.dsize == 0) {
1775 /* end of traverse */
1780 if (data.dsize == sizeof(struct ctdb_ltdb_header)) {
1781 /* empty records are deleted records in ctdb */
1785 if (state->fn(ctdb, key, data, state->private_data) != 0) {
1794 start a cluster wide traverse, calling the supplied fn on each record
1795 return the number of records traversed, or -1 on error
1797 int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
1800 struct ctdb_traverse_start t;
1803 uint64_t srvid = (getpid() | 0xFLL<<60);
1804 struct traverse_state state;
1808 state.private_data = private_data;
1811 ret = ctdb_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
1813 DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
1817 t.db_id = ctdb_db->db_id;
1821 data.dptr = (uint8_t *)&t;
1822 data.dsize = sizeof(t);
1824 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START, 0,
1825 data, NULL, NULL, &status, NULL, NULL);
1826 if (ret != 0 || status != 0) {
1827 DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
1828 ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state);
1832 while (!state.done) {
1833 event_loop_once(ctdb_db->ctdb->ev);
1836 ret = ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state);
1838 DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
1845 #define ISASCII(x) ((x>31)&&(x<128))
1847 called on each key during a catdb
1849 static int dumpdb_fn(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p)
1852 FILE *f = (FILE *)p;
1853 struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
1855 fprintf(f, "dmaster: %u\n", h->dmaster);
1856 fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
1858 fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
1859 for (i=0;i<key.dsize;i++) {
1860 if (ISASCII(key.dptr[i])) {
1861 fprintf(f, "%c", key.dptr[i]);
1863 fprintf(f, "\\%02X", key.dptr[i]);
1868 fprintf(f, "data(%u) = \"", (unsigned)data.dsize);
1869 for (i=sizeof(*h);i<data.dsize;i++) {
1870 if (ISASCII(data.dptr[i])) {
1871 fprintf(f, "%c", data.dptr[i]);
1873 fprintf(f, "\\%02X", data.dptr[i]);
1882 convenience function to list all keys to stdout
1884 int ctdb_dump_db(struct ctdb_db_context *ctdb_db, FILE *f)
1886 return ctdb_traverse(ctdb_db, dumpdb_fn, f);
1890 get the pid of a ctdb daemon
1892 int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
1897 ret = ctdb_control(ctdb, destnode, 0,
1898 CTDB_CONTROL_GET_PID, 0, tdb_null,
1899 NULL, NULL, &res, &timeout, NULL);
1901 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
1912 async freeze send control
1914 struct ctdb_client_control_state *
1915 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
1917 return ctdb_control_send(ctdb, destnode, priority,
1918 CTDB_CONTROL_FREEZE, 0, tdb_null,
1919 mem_ctx, &timeout, NULL);
1923 async freeze recv control
1925 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
1930 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1931 if ( (ret != 0) || (res != 0) ){
1932 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
1940 freeze databases of a certain priority
1942 int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
1944 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1945 struct ctdb_client_control_state *state;
1948 state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
1949 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
1950 talloc_free(tmp_ctx);
1955 /* Freeze all databases */
1956 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1960 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
1961 if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
1969 thaw databases of a certain priority
1971 int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
1976 ret = ctdb_control(ctdb, destnode, priority,
1977 CTDB_CONTROL_THAW, 0, tdb_null,
1978 NULL, NULL, &res, &timeout, NULL);
1979 if (ret != 0 || res != 0) {
1980 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
1987 /* thaw all databases */
1988 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1990 return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
1994 get pnn of a node, or -1
1996 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2001 ret = ctdb_control(ctdb, destnode, 0,
2002 CTDB_CONTROL_GET_PNN, 0, tdb_null,
2003 NULL, NULL, &res, &timeout, NULL);
2005 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
2013 get the monitoring mode of a remote node
2015 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
2020 ret = ctdb_control(ctdb, destnode, 0,
2021 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
2022 NULL, NULL, &res, &timeout, NULL);
2024 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
2035 set the monitoring mode of a remote node to active
2037 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2042 ret = ctdb_control(ctdb, destnode, 0,
2043 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
2044 NULL, NULL,NULL, &timeout, NULL);
2046 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
2056 set the monitoring mode of a remote node to disable
2058 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2063 ret = ctdb_control(ctdb, destnode, 0,
2064 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
2065 NULL, NULL, NULL, &timeout, NULL);
2067 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
2079 sent to a node to make it take over an ip address
2081 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
2082 uint32_t destnode, struct ctdb_public_ip *ip)
2085 struct ctdb_public_ipv4 ipv4;
2089 if (ip->addr.sa.sa_family == AF_INET) {
2091 ipv4.sin = ip->addr.ip;
2093 data.dsize = sizeof(ipv4);
2094 data.dptr = (uint8_t *)&ipv4;
2096 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
2097 NULL, &res, &timeout, NULL);
2099 data.dsize = sizeof(*ip);
2100 data.dptr = (uint8_t *)ip;
2102 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
2103 NULL, &res, &timeout, NULL);
2106 if (ret != 0 || res != 0) {
2107 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
2116 sent to a node to make it release an ip address
2118 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
2119 uint32_t destnode, struct ctdb_public_ip *ip)
2122 struct ctdb_public_ipv4 ipv4;
2126 if (ip->addr.sa.sa_family == AF_INET) {
2128 ipv4.sin = ip->addr.ip;
2130 data.dsize = sizeof(ipv4);
2131 data.dptr = (uint8_t *)&ipv4;
2133 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
2134 NULL, &res, &timeout, NULL);
2136 data.dsize = sizeof(*ip);
2137 data.dptr = (uint8_t *)ip;
2139 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
2140 NULL, &res, &timeout, NULL);
2143 if (ret != 0 || res != 0) {
2144 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
2155 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
2156 struct timeval timeout,
2158 const char *name, uint32_t *value)
2160 struct ctdb_control_get_tunable *t;
2161 TDB_DATA data, outdata;
2165 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
2166 data.dptr = talloc_size(ctdb, data.dsize);
2167 CTDB_NO_MEMORY(ctdb, data.dptr);
2169 t = (struct ctdb_control_get_tunable *)data.dptr;
2170 t->length = strlen(name)+1;
2171 memcpy(t->name, name, t->length);
2173 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
2174 &outdata, &res, &timeout, NULL);
2175 talloc_free(data.dptr);
2176 if (ret != 0 || res != 0) {
2177 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
2181 if (outdata.dsize != sizeof(uint32_t)) {
2182 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
2183 talloc_free(outdata.dptr);
2187 *value = *(uint32_t *)outdata.dptr;
2188 talloc_free(outdata.dptr);
2196 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
2197 struct timeval timeout,
2199 const char *name, uint32_t value)
2201 struct ctdb_control_set_tunable *t;
2206 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
2207 data.dptr = talloc_size(ctdb, data.dsize);
2208 CTDB_NO_MEMORY(ctdb, data.dptr);
2210 t = (struct ctdb_control_set_tunable *)data.dptr;
2211 t->length = strlen(name)+1;
2212 memcpy(t->name, name, t->length);
2215 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
2216 NULL, &res, &timeout, NULL);
2217 talloc_free(data.dptr);
2218 if (ret != 0 || res != 0) {
2219 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
2229 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
2230 struct timeval timeout,
2232 TALLOC_CTX *mem_ctx,
2233 const char ***list, uint32_t *count)
2238 struct ctdb_control_list_tunable *t;
2241 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
2242 mem_ctx, &outdata, &res, &timeout, NULL);
2243 if (ret != 0 || res != 0) {
2244 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
2248 t = (struct ctdb_control_list_tunable *)outdata.dptr;
2249 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
2250 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
2251 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
2252 talloc_free(outdata.dptr);
2256 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
2257 CTDB_NO_MEMORY(ctdb, p);
2259 talloc_free(outdata.dptr);
2264 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
2265 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
2266 CTDB_NO_MEMORY(ctdb, *list);
2267 (*list)[*count] = talloc_strdup(*list, s);
2268 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
2278 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
2279 struct timeval timeout, uint32_t destnode,
2280 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2286 ret = ctdb_control(ctdb, destnode, 0,
2287 CTDB_CONTROL_GET_PUBLIC_IPS, 0, tdb_null,
2288 mem_ctx, &outdata, &res, &timeout, NULL);
2289 if (ret == 0 && res == -1) {
2290 DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
2291 return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
2293 if (ret != 0 || res != 0) {
2294 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
2298 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
2299 talloc_free(outdata.dptr);
2304 int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
2305 struct timeval timeout, uint32_t destnode,
2306 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2311 struct ctdb_all_public_ipsv4 *ipsv4;
2313 ret = ctdb_control(ctdb, destnode, 0,
2314 CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null,
2315 mem_ctx, &outdata, &res, &timeout, NULL);
2316 if (ret != 0 || res != 0) {
2317 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
2321 ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
2322 len = offsetof(struct ctdb_all_public_ips, ips) +
2323 ipsv4->num*sizeof(struct ctdb_public_ip);
2324 *ips = talloc_zero_size(mem_ctx, len);
2325 CTDB_NO_MEMORY(ctdb, *ips);
2326 (*ips)->num = ipsv4->num;
2327 for (i=0; i<ipsv4->num; i++) {
2328 (*ips)->ips[i].pnn = ipsv4->ips[i].pnn;
2329 (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
2332 talloc_free(outdata.dptr);
2338 set/clear the permanent disabled bit on a remote node
2340 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
2341 uint32_t set, uint32_t clear)
2345 struct ctdb_node_map *nodemap=NULL;
2346 struct ctdb_node_flag_change c;
2347 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2352 /* find the recovery master */
2353 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
2355 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
2356 talloc_free(tmp_ctx);
2361 /* read the node flags from the recmaster */
2362 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
2364 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
2365 talloc_free(tmp_ctx);
2368 if (destnode >= nodemap->num) {
2369 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
2370 talloc_free(tmp_ctx);
2375 c.old_flags = nodemap->nodes[destnode].flags;
2376 c.new_flags = c.old_flags;
2378 c.new_flags &= ~clear;
2380 data.dsize = sizeof(c);
2381 data.dptr = (unsigned char *)&c;
2383 /* send the flags update to all connected nodes */
2384 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
2386 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
2388 timeout, false, data,
2391 DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
2393 talloc_free(tmp_ctx);
2397 talloc_free(tmp_ctx);
2405 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
2406 struct timeval timeout,
2408 struct ctdb_tunable *tunables)
2414 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
2415 &outdata, &res, &timeout, NULL);
2416 if (ret != 0 || res != 0) {
2417 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
2421 if (outdata.dsize != sizeof(*tunables)) {
2422 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
2423 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
2427 *tunables = *(struct ctdb_tunable *)outdata.dptr;
2428 talloc_free(outdata.dptr);
2433 add a public address to a node
2435 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
2436 struct timeval timeout,
2438 struct ctdb_control_ip_iface *pub)
2444 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2445 data.dptr = (unsigned char *)pub;
2447 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
2448 NULL, &res, &timeout, NULL);
2449 if (ret != 0 || res != 0) {
2450 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
2458 delete a public address from a node
2460 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
2461 struct timeval timeout,
2463 struct ctdb_control_ip_iface *pub)
2469 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2470 data.dptr = (unsigned char *)pub;
2472 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
2473 NULL, &res, &timeout, NULL);
2474 if (ret != 0 || res != 0) {
2475 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
2483 kill a tcp connection
2485 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
2486 struct timeval timeout,
2488 struct ctdb_control_killtcp *killtcp)
2494 data.dsize = sizeof(struct ctdb_control_killtcp);
2495 data.dptr = (unsigned char *)killtcp;
2497 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
2498 NULL, &res, &timeout, NULL);
2499 if (ret != 0 || res != 0) {
2500 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
2510 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
2511 struct timeval timeout,
2513 ctdb_sock_addr *addr,
2519 struct ctdb_control_gratious_arp *gratious_arp;
2520 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2523 len = strlen(ifname)+1;
2524 gratious_arp = talloc_size(tmp_ctx,
2525 offsetof(struct ctdb_control_gratious_arp, iface) + len);
2526 CTDB_NO_MEMORY(ctdb, gratious_arp);
2528 gratious_arp->addr = *addr;
2529 gratious_arp->len = len;
2530 memcpy(&gratious_arp->iface[0], ifname, len);
2533 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
2534 data.dptr = (unsigned char *)gratious_arp;
2536 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
2537 NULL, &res, &timeout, NULL);
2538 if (ret != 0 || res != 0) {
2539 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
2540 talloc_free(tmp_ctx);
2544 talloc_free(tmp_ctx);
2549 get a list of all tcp tickles that a node knows about for a particular vnn
2551 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
2552 struct timeval timeout, uint32_t destnode,
2553 TALLOC_CTX *mem_ctx,
2554 ctdb_sock_addr *addr,
2555 struct ctdb_control_tcp_tickle_list **list)
2558 TDB_DATA data, outdata;
2561 data.dptr = (uint8_t*)addr;
2562 data.dsize = sizeof(ctdb_sock_addr);
2564 ret = ctdb_control(ctdb, destnode, 0,
2565 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
2566 mem_ctx, &outdata, &status, NULL, NULL);
2567 if (ret != 0 || status != 0) {
2568 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
2572 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
2578 register a server id
2580 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
2581 struct timeval timeout,
2582 struct ctdb_server_id *id)
2588 data.dsize = sizeof(struct ctdb_server_id);
2589 data.dptr = (unsigned char *)id;
2591 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2592 CTDB_CONTROL_REGISTER_SERVER_ID,
2594 NULL, &res, &timeout, NULL);
2595 if (ret != 0 || res != 0) {
2596 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
2604 unregister a server id
2606 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
2607 struct timeval timeout,
2608 struct ctdb_server_id *id)
2614 data.dsize = sizeof(struct ctdb_server_id);
2615 data.dptr = (unsigned char *)id;
2617 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2618 CTDB_CONTROL_UNREGISTER_SERVER_ID,
2620 NULL, &res, &timeout, NULL);
2621 if (ret != 0 || res != 0) {
2622 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
2631 check if a server id exists
2633 if a server id does exist, return *status == 1, otherwise *status == 0
2635 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
2636 struct timeval timeout,
2638 struct ctdb_server_id *id,
2645 data.dsize = sizeof(struct ctdb_server_id);
2646 data.dptr = (unsigned char *)id;
2648 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
2650 NULL, &res, &timeout, NULL);
2652 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
2666 get the list of server ids that are registered on a node
2668 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
2669 TALLOC_CTX *mem_ctx,
2670 struct timeval timeout, uint32_t destnode,
2671 struct ctdb_server_id_list **svid_list)
2677 ret = ctdb_control(ctdb, destnode, 0,
2678 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
2679 mem_ctx, &outdata, &res, &timeout, NULL);
2680 if (ret != 0 || res != 0) {
2681 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
2685 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
2691 initialise the ctdb daemon for client applications
2693 NOTE: In current code the daemon does not fork. This is for testing purposes only
2694 and to simplify the code.
2696 struct ctdb_context *ctdb_init(struct event_context *ev)
2699 struct ctdb_context *ctdb;
2701 ctdb = talloc_zero(ev, struct ctdb_context);
2703 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
2707 ctdb->idr = idr_init(ctdb);
2708 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
2710 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
2712 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
2724 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
2726 ctdb->flags |= flags;
2730 setup the local socket name
2732 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
2734 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
2735 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
2741 return the pnn of this node
2743 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
2750 get the uptime of a remote node
2752 struct ctdb_client_control_state *
2753 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
2755 return ctdb_control_send(ctdb, destnode, 0,
2756 CTDB_CONTROL_UPTIME, 0, tdb_null,
2757 mem_ctx, &timeout, NULL);
2760 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
2766 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
2767 if (ret != 0 || res != 0) {
2768 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
2772 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
2777 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
2779 struct ctdb_client_control_state *state;
2781 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
2782 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
2786 send a control to execute the "recovered" event script on a node
2788 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2793 ret = ctdb_control(ctdb, destnode, 0,
2794 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
2795 NULL, NULL, &status, &timeout, NULL);
2796 if (ret != 0 || status != 0) {
2797 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
2805 callback for the async helpers used when sending the same control
2806 to multiple nodes in parallell.
2808 static void async_callback(struct ctdb_client_control_state *state)
2810 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
2811 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
2815 uint32_t destnode = state->c->hdr.destnode;
2817 /* one more node has responded with recmode data */
2820 /* if we failed to push the db, then return an error and let
2821 the main loop try again.
2823 if (state->state != CTDB_CONTROL_DONE) {
2824 if ( !data->dont_log_errors) {
2825 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
2828 if (data->fail_callback) {
2829 data->fail_callback(ctdb, destnode, res, outdata,
2830 data->callback_data);
2835 state->async.fn = NULL;
2837 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
2838 if ((ret != 0) || (res != 0)) {
2839 if ( !data->dont_log_errors) {
2840 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
2843 if (data->fail_callback) {
2844 data->fail_callback(ctdb, destnode, res, outdata,
2845 data->callback_data);
2848 if ((ret == 0) && (data->callback != NULL)) {
2849 data->callback(ctdb, destnode, res, outdata,
2850 data->callback_data);
2855 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
2857 /* set up the callback functions */
2858 state->async.fn = async_callback;
2859 state->async.private_data = data;
2861 /* one more control to wait for to complete */
2866 /* wait for up to the maximum number of seconds allowed
2867 or until all nodes we expect a response from has replied
2869 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
2871 while (data->count > 0) {
2872 event_loop_once(ctdb->ev);
2874 if (data->fail_count != 0) {
2875 if (!data->dont_log_errors) {
2876 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
2886 perform a simple control on the listed nodes
2887 The control cannot return data
2889 int ctdb_client_async_control(struct ctdb_context *ctdb,
2890 enum ctdb_controls opcode,
2893 struct timeval timeout,
2894 bool dont_log_errors,
2896 client_async_callback client_callback,
2897 client_async_callback fail_callback,
2898 void *callback_data)
2900 struct client_async_data *async_data;
2901 struct ctdb_client_control_state *state;
2904 async_data = talloc_zero(ctdb, struct client_async_data);
2905 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
2906 async_data->dont_log_errors = dont_log_errors;
2907 async_data->callback = client_callback;
2908 async_data->fail_callback = fail_callback;
2909 async_data->callback_data = callback_data;
2910 async_data->opcode = opcode;
2912 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
2914 /* loop over all nodes and send an async control to each of them */
2915 for (j=0; j<num_nodes; j++) {
2916 uint32_t pnn = nodes[j];
2918 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
2919 0, data, async_data, &timeout, NULL);
2920 if (state == NULL) {
2921 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
2922 talloc_free(async_data);
2926 ctdb_client_async_add(async_data, state);
2929 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
2930 talloc_free(async_data);
2934 talloc_free(async_data);
2938 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
2939 struct ctdb_vnn_map *vnn_map,
2940 TALLOC_CTX *mem_ctx,
2943 int i, j, num_nodes;
2946 for (i=num_nodes=0;i<vnn_map->size;i++) {
2947 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2953 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2954 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2956 for (i=j=0;i<vnn_map->size;i++) {
2957 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2960 nodes[j++] = vnn_map->map[i];
2966 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
2967 struct ctdb_node_map *node_map,
2968 TALLOC_CTX *mem_ctx,
2971 int i, j, num_nodes;
2974 for (i=num_nodes=0;i<node_map->num;i++) {
2975 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2978 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2984 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2985 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2987 for (i=j=0;i<node_map->num;i++) {
2988 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2991 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2994 nodes[j++] = node_map->nodes[i].pnn;
3000 uint32_t *list_of_active_nodes_except_pnn(struct ctdb_context *ctdb,
3001 struct ctdb_node_map *node_map,
3002 TALLOC_CTX *mem_ctx,
3005 int i, j, num_nodes;
3008 for (i=num_nodes=0;i<node_map->num;i++) {
3009 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3012 if (node_map->nodes[i].pnn == pnn) {
3018 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3019 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3021 for (i=j=0;i<node_map->num;i++) {
3022 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3025 if (node_map->nodes[i].pnn == pnn) {
3028 nodes[j++] = node_map->nodes[i].pnn;
3034 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
3035 struct ctdb_node_map *node_map,
3036 TALLOC_CTX *mem_ctx,
3039 int i, j, num_nodes;
3042 for (i=num_nodes=0;i<node_map->num;i++) {
3043 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3046 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3052 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3053 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3055 for (i=j=0;i<node_map->num;i++) {
3056 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3059 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3062 nodes[j++] = node_map->nodes[i].pnn;
3069 this is used to test if a pnn lock exists and if it exists will return
3070 the number of connections that pnn has reported or -1 if that recovery
3071 daemon is not running.
3074 ctdb_read_pnn_lock(int fd, int32_t pnn)
3079 lock.l_type = F_WRLCK;
3080 lock.l_whence = SEEK_SET;
3085 if (fcntl(fd, F_GETLK, &lock) != 0) {
3086 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3090 if (lock.l_type == F_UNLCK) {
3094 if (pread(fd, &c, 1, pnn) == -1) {
3095 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3103 get capabilities of a remote node
3105 struct ctdb_client_control_state *
3106 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3108 return ctdb_control_send(ctdb, destnode, 0,
3109 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3110 mem_ctx, &timeout, NULL);
3113 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3119 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3120 if ( (ret != 0) || (res != 0) ) {
3121 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3126 *capabilities = *((uint32_t *)outdata.dptr);
3132 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3134 struct ctdb_client_control_state *state;
3135 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3138 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3139 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3140 talloc_free(tmp_ctx);
3144 struct ctdb_transaction_handle {
3145 struct ctdb_db_context *ctdb_db;
3147 /* we store the reads and writes done under a transaction one
3148 list stores both reads and writes, the other just writes
3150 struct ctdb_marshall_buffer *m_all;
3151 struct ctdb_marshall_buffer *m_write;
3154 /* start a transaction on a database */
3155 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
3157 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3161 /* start a transaction on a database */
3162 static int ctdb_transaction_fetch_start(struct ctdb_transaction_handle *h)
3164 struct ctdb_record_handle *rh;
3167 struct ctdb_ltdb_header header;
3168 TALLOC_CTX *tmp_ctx;
3169 const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
3171 struct ctdb_db_context *ctdb_db = h->ctdb_db;
3174 key.dptr = discard_const(keyname);
3175 key.dsize = strlen(keyname);
3177 if (!ctdb_db->persistent) {
3178 DEBUG(DEBUG_ERR,(__location__ " Attempted transaction on non-persistent database\n"));
3183 tmp_ctx = talloc_new(h);
3185 rh = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, NULL);
3187 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch_lock database\n"));
3188 talloc_free(tmp_ctx);
3192 * store the pid in the database:
3193 * it is not enough that the node is dmaster...
3196 data.dptr = (unsigned char *)&pid;
3197 data.dsize = sizeof(pid_t);
3198 ret = ctdb_ltdb_store(ctdb_db, key, &(rh->header), data);
3200 DEBUG(DEBUG_ERR, (__location__ " Failed to store pid in "
3201 "transaction record\n"));
3202 talloc_free(tmp_ctx);
3208 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3210 DEBUG(DEBUG_ERR,(__location__ " Failed to start tdb transaction\n"));
3211 talloc_free(tmp_ctx);
3215 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, &data);
3216 if (ret != 0 || header.dmaster != ctdb_db->ctdb->pnn) {
3217 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3218 talloc_free(tmp_ctx);
3222 if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
3223 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3224 talloc_free(tmp_ctx);
3228 talloc_free(tmp_ctx);
3234 /* start a transaction on a database */
3235 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
3236 TALLOC_CTX *mem_ctx)
3238 struct ctdb_transaction_handle *h;
3241 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
3243 DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
3247 h->ctdb_db = ctdb_db;
3249 ret = ctdb_transaction_fetch_start(h);
3255 talloc_set_destructor(h, ctdb_transaction_destructor);
3263 fetch a record inside a transaction
3265 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
3266 TALLOC_CTX *mem_ctx,
3267 TDB_DATA key, TDB_DATA *data)
3269 struct ctdb_ltdb_header header;
3272 ZERO_STRUCT(header);
3274 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
3275 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3276 /* record doesn't exist yet */
3285 if (!h->in_replay) {
3286 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
3287 if (h->m_all == NULL) {
3288 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3297 stores a record inside a transaction
3299 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
3300 TDB_DATA key, TDB_DATA data)
3302 TALLOC_CTX *tmp_ctx = talloc_new(h);
3303 struct ctdb_ltdb_header header;
3307 ZERO_STRUCT(header);
3309 /* we need the header so we can update the RSN */
3310 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
3311 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3312 /* the record doesn't exist - create one with us as dmaster.
3313 This is only safe because we are in a transaction and this
3314 is a persistent database */
3315 ZERO_STRUCT(header);
3316 } else if (ret != 0) {
3317 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
3318 talloc_free(tmp_ctx);
3322 if (data.dsize == olddata.dsize &&
3323 memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
3324 /* save writing the same data */
3325 talloc_free(tmp_ctx);
3329 header.dmaster = h->ctdb_db->ctdb->pnn;
3332 if (!h->in_replay) {
3333 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
3334 if (h->m_all == NULL) {
3335 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3336 talloc_free(tmp_ctx);
3341 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
3342 if (h->m_write == NULL) {
3343 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3344 talloc_free(tmp_ctx);
3348 ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
3350 talloc_free(tmp_ctx);
3356 replay a transaction
3358 static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
3361 struct ctdb_rec_data *rec = NULL;
3363 h->in_replay = true;
3364 talloc_free(h->m_write);
3367 ret = ctdb_transaction_fetch_start(h);
3372 for (i=0;i<h->m_all->count;i++) {
3375 rec = ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
3377 DEBUG(DEBUG_ERR, (__location__ " Out of records in ctdb_replay_transaction?\n"));
3381 if (rec->reqid == 0) {
3383 if (ctdb_transaction_store(h, key, data) != 0) {
3388 TALLOC_CTX *tmp_ctx = talloc_new(h);
3390 if (ctdb_transaction_fetch(h, tmp_ctx, key, &data2) != 0) {
3391 talloc_free(tmp_ctx);
3394 if (data2.dsize != data.dsize ||
3395 memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
3396 /* the record has changed on us - we have to give up */
3397 talloc_free(tmp_ctx);
3400 talloc_free(tmp_ctx);
3407 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3413 commit a transaction
3415 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
3419 struct ctdb_context *ctdb = h->ctdb_db->ctdb;
3420 struct timeval timeout;
3421 enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
3423 talloc_set_destructor(h, NULL);
3425 /* our commit strategy is quite complex.
3427 - we first try to commit the changes to all other nodes
3429 - if that works, then we commit locally and we are done
3431 - if a commit on another node fails, then we need to cancel
3432 the transaction, then restart the transaction (thus
3433 opening a window of time for a pending recovery to
3434 complete), then replay the transaction, checking all the
3435 reads and writes (checking that reads give the same data,
3436 and writes succeed). Then we retry the transaction to the
3441 if (h->m_write == NULL) {
3442 /* no changes were made */
3443 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3448 /* tell ctdbd to commit to the other nodes */
3449 timeout = timeval_current_ofs(1, 0);
3450 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3451 retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY, 0,
3452 ctdb_marshall_finish(h->m_write), NULL, NULL, &status,
3454 if (ret != 0 || status != 0) {
3455 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3459 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3461 /* work out what error code we will give if we
3462 have to fail the operation */
3463 switch ((enum ctdb_trans2_commit_error)status) {
3464 case CTDB_TRANS2_COMMIT_SUCCESS:
3465 case CTDB_TRANS2_COMMIT_SOMEFAIL:
3466 case CTDB_TRANS2_COMMIT_TIMEOUT:
3467 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3469 case CTDB_TRANS2_COMMIT_ALLFAIL:
3470 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
3475 if (++retries == 10) {
3476 DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
3477 h->ctdb_db->db_id, retries, (unsigned)failure_control));
3478 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3479 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3480 tdb_null, NULL, NULL, NULL, NULL, NULL);
3485 if (ctdb_replay_transaction(h) != 0) {
3486 DEBUG(DEBUG_ERR,(__location__ " Failed to replay transaction\n"));
3487 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3488 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3489 tdb_null, NULL, NULL, NULL, NULL, NULL);
3495 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3498 /* do the real commit locally */
3499 ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
3501 DEBUG(DEBUG_ERR,(__location__ " Failed to commit transaction\n"));
3502 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3503 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3504 tdb_null, NULL, NULL, NULL, NULL, NULL);
3509 /* tell ctdbd that we are finished with our local commit */
3510 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3511 CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
3512 tdb_null, NULL, NULL, NULL, NULL, NULL);
3518 recovery daemon ping to main daemon
3520 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
3525 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
3526 ctdb, NULL, &res, NULL, NULL);
3527 if (ret != 0 || res != 0) {
3528 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
3535 /* when forking the main daemon and the child process needs to connect back
3536 * to the daemon as a client process, this function can be used to change
3537 * the ctdb context from daemon into client mode
3539 int switch_from_server_to_client(struct ctdb_context *ctdb)
3543 /* shutdown the transport */
3544 if (ctdb->methods) {
3545 ctdb->methods->shutdown(ctdb);
3548 /* get a new event context */
3549 talloc_free(ctdb->ev);
3550 ctdb->ev = event_context_init(ctdb);
3552 close(ctdb->daemon.sd);
3553 ctdb->daemon.sd = -1;
3555 /* the client does not need to be realtime */
3556 if (ctdb->do_setsched) {
3557 ctdb_restore_scheduler(ctdb);
3560 /* initialise ctdb */
3561 ret = ctdb_socket_connect(ctdb);
3563 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
3571 tell the main daemon we are starting a new monitor event script
3573 int ctdb_ctrl_event_script_init(struct ctdb_context *ctdb)
3578 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_INIT, 0, tdb_null,
3579 ctdb, NULL, &res, NULL, NULL);
3580 if (ret != 0 || res != 0) {
3581 DEBUG(DEBUG_ERR,("Failed to send event_script_init\n"));
3589 tell the main daemon we are starting a new monitor event script
3591 int ctdb_ctrl_event_script_finished(struct ctdb_context *ctdb)
3596 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_FINISHED, 0, tdb_null,
3597 ctdb, NULL, &res, NULL, NULL);
3598 if (ret != 0 || res != 0) {
3599 DEBUG(DEBUG_ERR,("Failed to send event_script_init\n"));
3607 tell the main daemon we are starting to run an eventscript
3609 int ctdb_ctrl_event_script_start(struct ctdb_context *ctdb, const char *name)
3615 data.dptr = discard_const(name);
3616 data.dsize = strlen(name)+1;
3618 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_START, 0, data,
3619 ctdb, NULL, &res, NULL, NULL);
3620 if (ret != 0 || res != 0) {
3621 DEBUG(DEBUG_ERR,("Failed to send event_script_start\n"));
3629 tell the main daemon the status of the script we ran
3631 int ctdb_ctrl_event_script_stop(struct ctdb_context *ctdb, int32_t result)
3637 data.dptr = (uint8_t *)&result;
3638 data.dsize = sizeof(result);
3640 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_STOP, 0, data,
3641 ctdb, NULL, &res, NULL, NULL);
3642 if (ret != 0 || res != 0) {
3643 DEBUG(DEBUG_ERR,("Failed to send event_script_stop\n"));
3651 tell the main daemon a script was disabled
3653 int ctdb_ctrl_event_script_disabled(struct ctdb_context *ctdb, const char *name)
3659 data.dptr = discard_const(name);
3660 data.dsize = strlen(name)+1;
3662 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_EVENT_SCRIPT_DISABLED, 0, data,
3663 ctdb, NULL, &res, NULL, NULL);
3664 if (ret != 0 || res != 0) {
3665 DEBUG(DEBUG_ERR,("Failed to send event_script_disabeld\n"));
3673 get the status of running the monitor eventscripts
3675 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
3676 struct timeval timeout, uint32_t destnode,
3677 TALLOC_CTX *mem_ctx,
3678 struct ctdb_monitoring_wire **script_status)
3684 ret = ctdb_control(ctdb, destnode, 0,
3685 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, tdb_null,
3686 mem_ctx, &outdata, &res, &timeout, NULL);
3687 if (ret != 0 || res != 0 || outdata.dsize == 0) {
3688 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
3692 *script_status = (struct ctdb_monitoring_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
3693 talloc_free(outdata.dptr);
3699 tell the main daemon how long it took to lock the reclock file
3701 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
3707 data.dptr = (uint8_t *)&latency;
3708 data.dsize = sizeof(latency);
3710 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
3711 ctdb, NULL, &res, NULL, NULL);
3712 if (ret != 0 || res != 0) {
3713 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
3721 get the name of the reclock file
3723 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
3724 uint32_t destnode, TALLOC_CTX *mem_ctx,
3731 ret = ctdb_control(ctdb, destnode, 0,
3732 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
3733 mem_ctx, &data, &res, &timeout, NULL);
3734 if (ret != 0 || res != 0) {
3738 if (data.dsize == 0) {
3741 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
3743 talloc_free(data.dptr);
3749 set the reclock filename for a node
3751 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
3757 if (reclock == NULL) {
3761 data.dsize = strlen(reclock) + 1;
3762 data.dptr = discard_const(reclock);
3765 ret = ctdb_control(ctdb, destnode, 0,
3766 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
3767 NULL, NULL, &res, &timeout, NULL);
3768 if (ret != 0 || res != 0) {
3769 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
3779 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3784 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
3785 ctdb, NULL, &res, &timeout, NULL);
3786 if (ret != 0 || res != 0) {
3787 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
3797 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3801 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
3802 ctdb, NULL, NULL, &timeout, NULL);
3804 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
3812 set the natgw state for a node
3814 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
3820 data.dsize = sizeof(natgwstate);
3821 data.dptr = (uint8_t *)&natgwstate;
3823 ret = ctdb_control(ctdb, destnode, 0,
3824 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
3825 NULL, NULL, &res, &timeout, NULL);
3826 if (ret != 0 || res != 0) {
3827 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
3835 set the lmaster role for a node
3837 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
3843 data.dsize = sizeof(lmasterrole);
3844 data.dptr = (uint8_t *)&lmasterrole;
3846 ret = ctdb_control(ctdb, destnode, 0,
3847 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
3848 NULL, NULL, &res, &timeout, NULL);
3849 if (ret != 0 || res != 0) {
3850 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
3858 set the recmaster role for a node
3860 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
3866 data.dsize = sizeof(recmasterrole);
3867 data.dptr = (uint8_t *)&recmasterrole;
3869 ret = ctdb_control(ctdb, destnode, 0,
3870 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
3871 NULL, NULL, &res, &timeout, NULL);
3872 if (ret != 0 || res != 0) {
3873 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
3880 /* enable an eventscript
3882 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
3888 data.dsize = strlen(script) + 1;
3889 data.dptr = discard_const(script);
3891 ret = ctdb_control(ctdb, destnode, 0,
3892 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
3893 NULL, NULL, &res, &timeout, NULL);
3894 if (ret != 0 || res != 0) {
3895 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
3902 /* disable an eventscript
3904 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
3910 data.dsize = strlen(script) + 1;
3911 data.dptr = discard_const(script);
3913 ret = ctdb_control(ctdb, destnode, 0,
3914 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
3915 NULL, NULL, &res, &timeout, NULL);
3916 if (ret != 0 || res != 0) {
3917 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
3925 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime)
3931 data.dsize = sizeof(*bantime);
3932 data.dptr = (uint8_t *)bantime;
3934 ret = ctdb_control(ctdb, destnode, 0,
3935 CTDB_CONTROL_SET_BAN_STATE, 0, data,
3936 NULL, NULL, &res, &timeout, NULL);
3937 if (ret != 0 || res != 0) {
3938 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
3946 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime)
3951 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3953 ret = ctdb_control(ctdb, destnode, 0,
3954 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
3955 tmp_ctx, &outdata, &res, &timeout, NULL);
3956 if (ret != 0 || res != 0) {
3957 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
3958 talloc_free(tmp_ctx);
3962 *bantime = (struct ctdb_ban_time *)talloc_steal(mem_ctx, outdata.dptr);
3963 talloc_free(tmp_ctx);
3969 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
3974 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3976 data.dptr = (uint8_t*)db_prio;
3977 data.dsize = sizeof(*db_prio);
3979 ret = ctdb_control(ctdb, destnode, 0,
3980 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
3981 tmp_ctx, NULL, &res, &timeout, NULL);
3982 if (ret != 0 || res != 0) {
3983 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
3984 talloc_free(tmp_ctx);
3988 talloc_free(tmp_ctx);
3993 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
3998 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4000 data.dptr = (uint8_t*)&db_id;
4001 data.dsize = sizeof(db_id);
4003 ret = ctdb_control(ctdb, destnode, 0,
4004 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
4005 tmp_ctx, NULL, &res, &timeout, NULL);
4006 if (ret != 0 || res < 0) {
4007 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4008 talloc_free(tmp_ctx);
4016 talloc_free(tmp_ctx);