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/tevent/tevent.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, bool updatetdb)
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);
94 for (fn=ctdb_db->calls;fn;fn=fn->next) {
95 if (fn->id == call->call_id) break;
98 ctdb_set_error(ctdb, "Unknown call id %u\n", call->call_id);
103 if (fn->fn(c) != 0) {
104 ctdb_set_error(ctdb, "ctdb_call %u failed\n", call->call_id);
109 /* we need to force the record to be written out if this was a remote access */
110 if (c->new_data == NULL) {
111 c->new_data = &c->record_data;
114 if (c->new_data && updatetdb) {
115 /* XXX check that we always have the lock here? */
116 if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
117 ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
124 call->reply_data = *c->reply_data;
126 talloc_steal(call, call->reply_data.dptr);
127 talloc_set_name_const(call->reply_data.dptr, __location__);
129 call->reply_data.dptr = NULL;
130 call->reply_data.dsize = 0;
132 call->status = c->status;
141 queue a packet for sending from client to daemon
143 static int ctdb_client_queue_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
145 return ctdb_queue_send(ctdb->daemon.queue, (uint8_t *)hdr, hdr->length);
150 called when a CTDB_REPLY_CALL packet comes in in the client
152 This packet comes in response to a CTDB_REQ_CALL request packet. It
153 contains any reply data from the call
155 static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
157 struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
158 struct ctdb_client_call_state *state;
160 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_call_state);
162 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
166 if (hdr->reqid != state->reqid) {
167 /* we found a record but it was the wrong one */
168 DEBUG(DEBUG_ERR, ("Dropped client call reply with reqid:%u\n",hdr->reqid));
172 state->call->reply_data.dptr = c->data;
173 state->call->reply_data.dsize = c->datalen;
174 state->call->status = c->status;
176 talloc_steal(state, c);
178 state->state = CTDB_CALL_DONE;
180 if (state->async.fn) {
181 state->async.fn(state);
185 static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
188 this is called in the client, when data comes in from the daemon
190 static void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
192 struct ctdb_context *ctdb = talloc_get_type(args, struct ctdb_context);
193 struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
196 /* place the packet as a child of a tmp_ctx. We then use
197 talloc_free() below to free it. If any of the calls want
198 to keep it, then they will steal it somewhere else, and the
199 talloc_free() will be a no-op */
200 tmp_ctx = talloc_new(ctdb);
201 talloc_steal(tmp_ctx, hdr);
204 DEBUG(DEBUG_INFO,("Daemon has exited - shutting down client\n"));
208 if (cnt < sizeof(*hdr)) {
209 DEBUG(DEBUG_CRIT,("Bad packet length %u in client\n", (unsigned)cnt));
212 if (cnt != hdr->length) {
213 ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
214 (unsigned)hdr->length, (unsigned)cnt);
218 if (hdr->ctdb_magic != CTDB_MAGIC) {
219 ctdb_set_error(ctdb, "Non CTDB packet rejected in client\n");
223 if (hdr->ctdb_version != CTDB_VERSION) {
224 ctdb_set_error(ctdb, "Bad CTDB version 0x%x rejected in client\n", hdr->ctdb_version);
228 switch (hdr->operation) {
229 case CTDB_REPLY_CALL:
230 ctdb_client_reply_call(ctdb, hdr);
233 case CTDB_REQ_MESSAGE:
234 ctdb_request_message(ctdb, hdr);
237 case CTDB_REPLY_CONTROL:
238 ctdb_client_reply_control(ctdb, hdr);
242 DEBUG(DEBUG_CRIT,("bogus operation code:%u\n",hdr->operation));
246 talloc_free(tmp_ctx);
250 connect with exponential backoff, thanks Stevens
252 #define CONNECT_MAXSLEEP 64
253 static int ctdb_connect_retry(struct ctdb_context *ctdb)
255 struct sockaddr_un addr;
259 memset(&addr, 0, sizeof(addr));
260 addr.sun_family = AF_UNIX;
261 strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path));
263 for (secs = 1; secs <= CONNECT_MAXSLEEP; secs *= 2) {
264 ret = connect(ctdb->daemon.sd, (struct sockaddr *)&addr,
266 if ((ret == 0) || (errno != EAGAIN)) {
270 if (secs <= (CONNECT_MAXSLEEP / 2)) {
271 DEBUG(DEBUG_ERR,("connect failed: %s, retry in %d second(s)\n",
272 strerror(errno), secs));
281 connect to a unix domain socket
283 int ctdb_socket_connect(struct ctdb_context *ctdb)
285 ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
286 if (ctdb->daemon.sd == -1) {
287 DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
291 set_nonblocking(ctdb->daemon.sd);
292 set_close_on_exec(ctdb->daemon.sd);
294 if (ctdb_connect_retry(ctdb) == -1) {
295 DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
296 close(ctdb->daemon.sd);
297 ctdb->daemon.sd = -1;
301 ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
303 ctdb_client_read_cb, ctdb, "to-ctdbd");
308 struct ctdb_record_handle {
309 struct ctdb_db_context *ctdb_db;
312 struct ctdb_ltdb_header header;
317 make a recv call to the local ctdb daemon - called from client context
319 This is called when the program wants to wait for a ctdb_call to complete and get the
320 results. This call will block unless the call has already completed.
322 int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
328 while (state->state < CTDB_CALL_DONE) {
329 event_loop_once(state->ctdb_db->ctdb->ev);
331 if (state->state != CTDB_CALL_DONE) {
332 DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
337 if (state->call->reply_data.dsize) {
338 call->reply_data.dptr = talloc_memdup(state->ctdb_db,
339 state->call->reply_data.dptr,
340 state->call->reply_data.dsize);
341 call->reply_data.dsize = state->call->reply_data.dsize;
343 call->reply_data.dptr = NULL;
344 call->reply_data.dsize = 0;
346 call->status = state->call->status;
356 destroy a ctdb_call in client
358 static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
360 ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
365 construct an event driven local ctdb_call
367 this is used so that locally processed ctdb_call requests are processed
368 in an event driven manner
370 static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
371 struct ctdb_call *call,
372 struct ctdb_ltdb_header *header,
375 struct ctdb_client_call_state *state;
376 struct ctdb_context *ctdb = ctdb_db->ctdb;
379 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
380 CTDB_NO_MEMORY_NULL(ctdb, state);
381 state->call = talloc_zero(state, struct ctdb_call);
382 CTDB_NO_MEMORY_NULL(ctdb, state->call);
384 talloc_steal(state, data->dptr);
386 state->state = CTDB_CALL_DONE;
387 *(state->call) = *call;
388 state->ctdb_db = ctdb_db;
390 ret = ctdb_call_local(ctdb_db, state->call, header, state, data, true);
396 make a ctdb call to the local daemon - async send. Called from client context.
398 This constructs a ctdb_call request and queues it for processing.
399 This call never blocks.
401 struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
402 struct ctdb_call *call)
404 struct ctdb_client_call_state *state;
405 struct ctdb_context *ctdb = ctdb_db->ctdb;
406 struct ctdb_ltdb_header header;
410 struct ctdb_req_call *c;
412 /* if the domain socket is not yet open, open it */
413 if (ctdb->daemon.sd==-1) {
414 ctdb_socket_connect(ctdb);
417 ret = ctdb_ltdb_lock(ctdb_db, call->key);
419 DEBUG(DEBUG_ERR,(__location__ " Failed to get chainlock\n"));
423 ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
425 if ((call->flags & CTDB_IMMEDIATE_MIGRATION) && (header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
429 if (ret == 0 && header.dmaster == ctdb->pnn) {
430 state = ctdb_client_call_local_send(ctdb_db, call, &header, &data);
431 talloc_free(data.dptr);
432 ctdb_ltdb_unlock(ctdb_db, call->key);
436 ctdb_ltdb_unlock(ctdb_db, call->key);
437 talloc_free(data.dptr);
439 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
441 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state\n"));
444 state->call = talloc_zero(state, struct ctdb_call);
445 if (state->call == NULL) {
446 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state->call\n"));
450 len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
451 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CALL, len, struct ctdb_req_call);
453 DEBUG(DEBUG_ERR, (__location__ " failed to allocate packet\n"));
457 state->reqid = ctdb_reqid_new(ctdb, state);
458 state->ctdb_db = ctdb_db;
459 talloc_set_destructor(state, ctdb_client_call_destructor);
461 c->hdr.reqid = state->reqid;
462 c->flags = call->flags;
463 c->db_id = ctdb_db->db_id;
464 c->callid = call->call_id;
466 c->keylen = call->key.dsize;
467 c->calldatalen = call->call_data.dsize;
468 memcpy(&c->data[0], call->key.dptr, call->key.dsize);
469 memcpy(&c->data[call->key.dsize],
470 call->call_data.dptr, call->call_data.dsize);
471 *(state->call) = *call;
472 state->call->call_data.dptr = &c->data[call->key.dsize];
473 state->call->key.dptr = &c->data[0];
475 state->state = CTDB_CALL_WAIT;
478 ctdb_client_queue_pkt(ctdb, &c->hdr);
485 full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
487 int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
489 struct ctdb_client_call_state *state;
491 state = ctdb_call_send(ctdb_db, call);
492 return ctdb_call_recv(state, call);
497 tell the daemon what messaging srvid we will use, and register the message
498 handler function in the client
500 int ctdb_client_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid,
501 ctdb_msg_fn_t handler,
508 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_REGISTER_SRVID, 0,
509 tdb_null, NULL, NULL, &status, NULL, NULL);
510 if (res != 0 || status != 0) {
511 DEBUG(DEBUG_ERR,("Failed to register srvid %llu\n", (unsigned long long)srvid));
515 /* also need to register the handler with our own ctdb structure */
516 return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
520 tell the daemon we no longer want a srvid
522 int ctdb_client_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid, void *private_data)
527 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_DEREGISTER_SRVID, 0,
528 tdb_null, NULL, NULL, &status, NULL, NULL);
529 if (res != 0 || status != 0) {
530 DEBUG(DEBUG_ERR,("Failed to deregister srvid %llu\n", (unsigned long long)srvid));
534 /* also need to register the handler with our own ctdb structure */
535 ctdb_deregister_message_handler(ctdb, srvid, private_data);
541 send a message - from client context
543 int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t pnn,
544 uint64_t srvid, TDB_DATA data)
546 struct ctdb_req_message *r;
549 len = offsetof(struct ctdb_req_message, data) + data.dsize;
550 r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
551 len, struct ctdb_req_message);
552 CTDB_NO_MEMORY(ctdb, r);
554 r->hdr.destnode = pnn;
556 r->datalen = data.dsize;
557 memcpy(&r->data[0], data.dptr, data.dsize);
559 res = ctdb_client_queue_pkt(ctdb, &r->hdr);
570 cancel a ctdb_fetch_lock operation, releasing the lock
572 static int fetch_lock_destructor(struct ctdb_record_handle *h)
574 ctdb_ltdb_unlock(h->ctdb_db, h->key);
579 force the migration of a record to this node
581 static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
583 struct ctdb_call call;
585 call.call_id = CTDB_NULL_FUNC;
587 call.flags = CTDB_IMMEDIATE_MIGRATION;
588 return ctdb_call(ctdb_db, &call);
592 try to fetch a readonly copy of a record
595 ctdb_client_fetch_readonly(struct ctdb_db_context *ctdb_db, TDB_DATA key, TALLOC_CTX *mem_ctx, struct ctdb_ltdb_header **hdr, TDB_DATA *data)
599 struct ctdb_call call;
602 call.call_id = CTDB_FETCH_WITH_HEADER_FUNC;
603 call.call_data.dptr = NULL;
604 call.call_data.dsize = 0;
606 call.flags = CTDB_WANT_READONLY;
607 ret = ctdb_call(ctdb_db, &call);
612 if (call.reply_data.dsize < sizeof(struct ctdb_ltdb_header)) {
616 *hdr = talloc_memdup(mem_ctx, &call.reply_data.dptr[0], sizeof(struct ctdb_ltdb_header));
618 talloc_free(call.reply_data.dptr);
622 data->dsize = call.reply_data.dsize - sizeof(struct ctdb_ltdb_header);
623 data->dptr = talloc_memdup(mem_ctx, &call.reply_data.dptr[sizeof(struct ctdb_ltdb_header)], data->dsize);
624 if (data->dptr == NULL) {
625 talloc_free(call.reply_data.dptr);
634 get a lock on a record, and return the records data. Blocks until it gets the lock
636 struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
637 TDB_DATA key, TDB_DATA *data)
640 struct ctdb_record_handle *h;
643 procedure is as follows:
645 1) get the chain lock.
646 2) check if we are dmaster
647 3) if we are the dmaster then return handle
648 4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
650 5) when we get the reply, goto (1)
653 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
658 h->ctdb_db = ctdb_db;
660 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
661 if (h->key.dptr == NULL) {
667 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize,
668 (const char *)key.dptr));
671 /* step 1 - get the chain lock */
672 ret = ctdb_ltdb_lock(ctdb_db, key);
674 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
679 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
681 talloc_set_destructor(h, fetch_lock_destructor);
683 ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
685 /* when torturing, ensure we test the remote path */
686 if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
688 h->header.dmaster = (uint32_t)-1;
692 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
694 if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
695 ctdb_ltdb_unlock(ctdb_db, key);
696 ret = ctdb_client_force_migration(ctdb_db, key);
698 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
705 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
710 get a readonly lock on a record, and return the records data. Blocks until it gets the lock
712 struct ctdb_record_handle *
713 ctdb_fetch_readonly_lock(
714 struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
715 TDB_DATA key, TDB_DATA *data,
719 struct ctdb_record_handle *h;
720 struct ctdb_ltdb_header *roheader = NULL;
722 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
727 h->ctdb_db = ctdb_db;
729 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
730 if (h->key.dptr == NULL) {
741 talloc_free(roheader);
744 talloc_free(data->dptr);
748 /* Lock the record/chain */
749 ret = ctdb_ltdb_lock(ctdb_db, key);
751 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
756 talloc_set_destructor(h, fetch_lock_destructor);
758 /* Check if record exists yet in the TDB */
759 ret = ctdb_ltdb_fetch_readonly(ctdb_db, key, &h->header, h, data);
761 ctdb_ltdb_unlock(ctdb_db, key);
762 ret = ctdb_client_force_migration(ctdb_db, key);
764 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
771 /* if this is a request for read/write and we have delegations
772 we have to revoke all delegations first
775 && (h->header.dmaster == ctdb_db->ctdb->pnn)
776 && (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
777 ctdb_ltdb_unlock(ctdb_db, key);
778 ret = ctdb_client_force_migration(ctdb_db, key);
780 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
787 /* if we are dmaster, just return the handle */
788 if (h->header.dmaster == ctdb_db->ctdb->pnn) {
792 if (read_only != 0) {
793 TDB_DATA rodata = {NULL, 0};
795 if ((h->header.flags & CTDB_REC_RO_HAVE_READONLY)
796 || (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
800 ctdb_ltdb_unlock(ctdb_db, key);
801 ret = ctdb_client_fetch_readonly(ctdb_db, key, h, &roheader, &rodata);
803 DEBUG(DEBUG_ERR,("ctdb_fetch_readonly_lock: failed. force migration and try again\n"));
804 ret = ctdb_client_force_migration(ctdb_db, key);
806 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
814 if (!(roheader->flags&CTDB_REC_RO_HAVE_READONLY)) {
815 ret = ctdb_client_force_migration(ctdb_db, key);
817 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
825 ret = ctdb_ltdb_lock(ctdb_db, key);
827 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
832 ret = ctdb_ltdb_fetch_readonly(ctdb_db, key, &h->header, h, data);
834 ctdb_ltdb_unlock(ctdb_db, key);
836 ret = ctdb_client_force_migration(ctdb_db, key);
838 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
846 if (h->header.rsn >= roheader->rsn) {
847 DEBUG(DEBUG_ERR,("READONLY RECORD: Too small RSN, migrate and try again\n"));
848 ctdb_ltdb_unlock(ctdb_db, key);
850 ret = ctdb_client_force_migration(ctdb_db, key);
852 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
860 if (ctdb_ltdb_store(ctdb_db, key, roheader, rodata) != 0) {
861 ctdb_ltdb_unlock(ctdb_db, key);
863 ret = ctdb_client_force_migration(ctdb_db, key);
865 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
875 /* we are not dmaster and this was not a request for a readonly lock
876 * so unlock the record, migrate it and try again
878 ctdb_ltdb_unlock(ctdb_db, key);
879 ret = ctdb_client_force_migration(ctdb_db, key);
881 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
889 store some data to the record that was locked with ctdb_fetch_lock()
891 int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
893 if (h->ctdb_db->persistent) {
894 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
898 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
902 non-locking fetch of a record
904 int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
905 TDB_DATA key, TDB_DATA *data)
907 struct ctdb_call call;
910 call.call_id = CTDB_FETCH_FUNC;
911 call.call_data.dptr = NULL;
912 call.call_data.dsize = 0;
915 ret = ctdb_call(ctdb_db, &call);
918 *data = call.reply_data;
919 talloc_steal(mem_ctx, data->dptr);
928 called when a control completes or timesout to invoke the callback
929 function the user provided
931 static void invoke_control_callback(struct event_context *ev, struct timed_event *te,
932 struct timeval t, void *private_data)
934 struct ctdb_client_control_state *state;
935 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
938 state = talloc_get_type(private_data, struct ctdb_client_control_state);
939 talloc_steal(tmp_ctx, state);
941 ret = ctdb_control_recv(state->ctdb, state, state,
946 talloc_free(tmp_ctx);
950 called when a CTDB_REPLY_CONTROL packet comes in in the client
952 This packet comes in response to a CTDB_REQ_CONTROL request packet. It
953 contains any reply data from the control
955 static void ctdb_client_reply_control(struct ctdb_context *ctdb,
956 struct ctdb_req_header *hdr)
958 struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
959 struct ctdb_client_control_state *state;
961 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_control_state);
963 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
967 if (hdr->reqid != state->reqid) {
968 /* we found a record but it was the wrong one */
969 DEBUG(DEBUG_ERR, ("Dropped orphaned reply control with reqid:%u\n",hdr->reqid));
973 state->outdata.dptr = c->data;
974 state->outdata.dsize = c->datalen;
975 state->status = c->status;
977 state->errormsg = talloc_strndup(state,
978 (char *)&c->data[c->datalen],
982 /* state->outdata now uses resources from c so we dont want c
983 to just dissappear from under us while state is still alive
985 talloc_steal(state, c);
987 state->state = CTDB_CONTROL_DONE;
989 /* if we had a callback registered for this control, pull the response
990 and call the callback.
992 if (state->async.fn) {
993 event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
999 destroy a ctdb_control in client
1001 static int ctdb_control_destructor(struct ctdb_client_control_state *state)
1003 ctdb_reqid_remove(state->ctdb, state->reqid);
1008 /* time out handler for ctdb_control */
1009 static void control_timeout_func(struct event_context *ev, struct timed_event *te,
1010 struct timeval t, void *private_data)
1012 struct ctdb_client_control_state *state = talloc_get_type(private_data, struct ctdb_client_control_state);
1014 DEBUG(DEBUG_ERR,(__location__ " control timed out. reqid:%u opcode:%u "
1015 "dstnode:%u\n", state->reqid, state->c->opcode,
1016 state->c->hdr.destnode));
1018 state->state = CTDB_CONTROL_TIMEOUT;
1020 /* if we had a callback registered for this control, pull the response
1021 and call the callback.
1023 if (state->async.fn) {
1024 event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
1028 /* async version of send control request */
1029 struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
1030 uint32_t destnode, uint64_t srvid,
1031 uint32_t opcode, uint32_t flags, TDB_DATA data,
1032 TALLOC_CTX *mem_ctx,
1033 struct timeval *timeout,
1036 struct ctdb_client_control_state *state;
1038 struct ctdb_req_control *c;
1045 /* if the domain socket is not yet open, open it */
1046 if (ctdb->daemon.sd==-1) {
1047 ctdb_socket_connect(ctdb);
1050 state = talloc_zero(mem_ctx, struct ctdb_client_control_state);
1051 CTDB_NO_MEMORY_NULL(ctdb, state);
1054 state->reqid = ctdb_reqid_new(ctdb, state);
1055 state->state = CTDB_CONTROL_WAIT;
1056 state->errormsg = NULL;
1058 talloc_set_destructor(state, ctdb_control_destructor);
1060 len = offsetof(struct ctdb_req_control, data) + data.dsize;
1061 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
1062 len, struct ctdb_req_control);
1064 CTDB_NO_MEMORY_NULL(ctdb, c);
1065 c->hdr.reqid = state->reqid;
1066 c->hdr.destnode = destnode;
1071 c->datalen = data.dsize;
1073 memcpy(&c->data[0], data.dptr, data.dsize);
1077 if (timeout && !timeval_is_zero(timeout)) {
1078 event_add_timed(ctdb->ev, state, *timeout, control_timeout_func, state);
1081 ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
1087 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
1096 /* async version of receive control reply */
1097 int ctdb_control_recv(struct ctdb_context *ctdb,
1098 struct ctdb_client_control_state *state,
1099 TALLOC_CTX *mem_ctx,
1100 TDB_DATA *outdata, int32_t *status, char **errormsg)
1102 TALLOC_CTX *tmp_ctx;
1104 if (status != NULL) {
1107 if (errormsg != NULL) {
1111 if (state == NULL) {
1115 /* prevent double free of state */
1116 tmp_ctx = talloc_new(ctdb);
1117 talloc_steal(tmp_ctx, state);
1119 /* loop one event at a time until we either timeout or the control
1122 while (state->state == CTDB_CONTROL_WAIT) {
1123 event_loop_once(ctdb->ev);
1126 if (state->state != CTDB_CONTROL_DONE) {
1127 DEBUG(DEBUG_ERR,(__location__ " ctdb_control_recv failed\n"));
1128 if (state->async.fn) {
1129 state->async.fn(state);
1131 talloc_free(tmp_ctx);
1135 if (state->errormsg) {
1136 DEBUG(DEBUG_ERR,("ctdb_control error: '%s'\n", state->errormsg));
1138 (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
1140 if (state->async.fn) {
1141 state->async.fn(state);
1143 talloc_free(tmp_ctx);
1148 *outdata = state->outdata;
1149 outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
1153 *status = state->status;
1156 if (state->async.fn) {
1157 state->async.fn(state);
1160 talloc_free(tmp_ctx);
1167 send a ctdb control message
1168 timeout specifies how long we should wait for a reply.
1169 if timeout is NULL we wait indefinitely
1171 int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
1172 uint32_t opcode, uint32_t flags, TDB_DATA data,
1173 TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
1174 struct timeval *timeout,
1177 struct ctdb_client_control_state *state;
1179 state = ctdb_control_send(ctdb, destnode, srvid, opcode,
1180 flags, data, mem_ctx,
1182 return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
1190 a process exists call. Returns 0 if process exists, -1 otherwise
1192 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
1198 data.dptr = (uint8_t*)&pid;
1199 data.dsize = sizeof(pid);
1201 ret = ctdb_control(ctdb, destnode, 0,
1202 CTDB_CONTROL_PROCESS_EXISTS, 0, data,
1203 NULL, NULL, &status, NULL, NULL);
1205 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
1213 get remote statistics
1215 int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
1221 ret = ctdb_control(ctdb, destnode, 0,
1222 CTDB_CONTROL_STATISTICS, 0, tdb_null,
1223 ctdb, &data, &res, NULL, NULL);
1224 if (ret != 0 || res != 0) {
1225 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
1229 if (data.dsize != sizeof(struct ctdb_statistics)) {
1230 DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
1231 (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
1235 *status = *(struct ctdb_statistics *)data.dptr;
1236 talloc_free(data.dptr);
1242 shutdown a remote ctdb node
1244 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1246 struct ctdb_client_control_state *state;
1248 state = ctdb_control_send(ctdb, destnode, 0,
1249 CTDB_CONTROL_SHUTDOWN, 0, tdb_null,
1250 NULL, &timeout, NULL);
1251 if (state == NULL) {
1252 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
1260 get vnn map from a remote node
1262 int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
1267 struct ctdb_vnn_map_wire *map;
1269 ret = ctdb_control(ctdb, destnode, 0,
1270 CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
1271 mem_ctx, &outdata, &res, &timeout, NULL);
1272 if (ret != 0 || res != 0) {
1273 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
1277 map = (struct ctdb_vnn_map_wire *)outdata.dptr;
1278 if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
1279 outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
1280 DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
1284 (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
1285 CTDB_NO_MEMORY(ctdb, *vnnmap);
1286 (*vnnmap)->generation = map->generation;
1287 (*vnnmap)->size = map->size;
1288 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
1290 CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
1291 memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
1292 talloc_free(outdata.dptr);
1299 get the recovery mode of a remote node
1301 struct ctdb_client_control_state *
1302 ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
1304 return ctdb_control_send(ctdb, destnode, 0,
1305 CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
1306 mem_ctx, &timeout, NULL);
1309 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
1314 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1316 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
1321 *recmode = (uint32_t)res;
1327 int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
1329 struct ctdb_client_control_state *state;
1331 state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
1332 return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
1339 set the recovery mode of a remote node
1341 int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
1347 data.dsize = sizeof(uint32_t);
1348 data.dptr = (unsigned char *)&recmode;
1350 ret = ctdb_control(ctdb, destnode, 0,
1351 CTDB_CONTROL_SET_RECMODE, 0, data,
1352 NULL, NULL, &res, &timeout, NULL);
1353 if (ret != 0 || res != 0) {
1354 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
1364 get the recovery master of a remote node
1366 struct ctdb_client_control_state *
1367 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
1368 struct timeval timeout, uint32_t destnode)
1370 return ctdb_control_send(ctdb, destnode, 0,
1371 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
1372 mem_ctx, &timeout, NULL);
1375 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
1380 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1382 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
1387 *recmaster = (uint32_t)res;
1393 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
1395 struct ctdb_client_control_state *state;
1397 state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
1398 return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
1403 set the recovery master of a remote node
1405 int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
1412 data.dsize = sizeof(uint32_t);
1413 data.dptr = (unsigned char *)&recmaster;
1415 ret = ctdb_control(ctdb, destnode, 0,
1416 CTDB_CONTROL_SET_RECMASTER, 0, data,
1417 NULL, NULL, &res, &timeout, NULL);
1418 if (ret != 0 || res != 0) {
1419 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
1428 get a list of databases off a remote node
1430 int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1431 TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
1437 ret = ctdb_control(ctdb, destnode, 0,
1438 CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
1439 mem_ctx, &outdata, &res, &timeout, NULL);
1440 if (ret != 0 || res != 0) {
1441 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
1445 *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1446 talloc_free(outdata.dptr);
1452 get a list of nodes (vnn and flags ) from a remote node
1454 int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
1455 struct timeval timeout, uint32_t destnode,
1456 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1462 ret = ctdb_control(ctdb, destnode, 0,
1463 CTDB_CONTROL_GET_NODEMAP, 0, tdb_null,
1464 mem_ctx, &outdata, &res, &timeout, NULL);
1465 if (ret == 0 && res == -1 && outdata.dsize == 0) {
1466 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
1467 return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
1469 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1470 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
1474 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1475 talloc_free(outdata.dptr);
1481 old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
1483 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb,
1484 struct timeval timeout, uint32_t destnode,
1485 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1489 struct ctdb_node_mapv4 *nodemapv4;
1492 ret = ctdb_control(ctdb, destnode, 0,
1493 CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null,
1494 mem_ctx, &outdata, &res, &timeout, NULL);
1495 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1496 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
1500 nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
1502 len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
1503 (*nodemap) = talloc_zero_size(mem_ctx, len);
1504 CTDB_NO_MEMORY(ctdb, (*nodemap));
1506 (*nodemap)->num = nodemapv4->num;
1507 for (i=0; i<nodemapv4->num; i++) {
1508 (*nodemap)->nodes[i].pnn = nodemapv4->nodes[i].pnn;
1509 (*nodemap)->nodes[i].flags = nodemapv4->nodes[i].flags;
1510 (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
1511 (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
1514 talloc_free(outdata.dptr);
1520 drop the transport, reload the nodes file and restart the transport
1522 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
1523 struct timeval timeout, uint32_t destnode)
1528 ret = ctdb_control(ctdb, destnode, 0,
1529 CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
1530 NULL, NULL, &res, &timeout, NULL);
1531 if (ret != 0 || res != 0) {
1532 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
1541 set vnn map on a node
1543 int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1544 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
1549 struct ctdb_vnn_map_wire *map;
1552 len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
1553 map = talloc_size(mem_ctx, len);
1554 CTDB_NO_MEMORY(ctdb, map);
1556 map->generation = vnnmap->generation;
1557 map->size = vnnmap->size;
1558 memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
1561 data.dptr = (uint8_t *)map;
1563 ret = ctdb_control(ctdb, destnode, 0,
1564 CTDB_CONTROL_SETVNNMAP, 0, data,
1565 NULL, NULL, &res, &timeout, NULL);
1566 if (ret != 0 || res != 0) {
1567 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
1578 async send for pull database
1580 struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
1581 struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
1582 uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
1585 struct ctdb_control_pulldb *pull;
1586 struct ctdb_client_control_state *state;
1588 pull = talloc(mem_ctx, struct ctdb_control_pulldb);
1589 CTDB_NO_MEMORY_NULL(ctdb, pull);
1592 pull->lmaster = lmaster;
1594 indata.dsize = sizeof(struct ctdb_control_pulldb);
1595 indata.dptr = (unsigned char *)pull;
1597 state = ctdb_control_send(ctdb, destnode, 0,
1598 CTDB_CONTROL_PULL_DB, 0, indata,
1599 mem_ctx, &timeout, NULL);
1606 async recv for pull database
1608 int ctdb_ctrl_pulldb_recv(
1609 struct ctdb_context *ctdb,
1610 TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state,
1616 ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
1617 if ( (ret != 0) || (res != 0) ){
1618 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
1626 pull all keys and records for a specific database on a node
1628 int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode,
1629 uint32_t dbid, uint32_t lmaster,
1630 TALLOC_CTX *mem_ctx, struct timeval timeout,
1633 struct ctdb_client_control_state *state;
1635 state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
1638 return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
1643 change dmaster for all keys in the database to the new value
1645 int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1646 TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
1652 indata.dsize = 2*sizeof(uint32_t);
1653 indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
1655 ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
1656 ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
1658 ret = ctdb_control(ctdb, destnode, 0,
1659 CTDB_CONTROL_SET_DMASTER, 0, indata,
1660 NULL, NULL, &res, &timeout, NULL);
1661 if (ret != 0 || res != 0) {
1662 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
1670 ping a node, return number of clients connected
1672 int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
1677 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0,
1678 tdb_null, NULL, NULL, &res, NULL, NULL);
1686 find the real path to a ltdb
1688 int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1695 data.dptr = (uint8_t *)&dbid;
1696 data.dsize = sizeof(dbid);
1698 ret = ctdb_control(ctdb, destnode, 0,
1699 CTDB_CONTROL_GETDBPATH, 0, data,
1700 mem_ctx, &data, &res, &timeout, NULL);
1701 if (ret != 0 || res != 0) {
1705 (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1706 if ((*path) == NULL) {
1710 talloc_free(data.dptr);
1716 find the name of a db
1718 int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1725 data.dptr = (uint8_t *)&dbid;
1726 data.dsize = sizeof(dbid);
1728 ret = ctdb_control(ctdb, destnode, 0,
1729 CTDB_CONTROL_GET_DBNAME, 0, data,
1730 mem_ctx, &data, &res, &timeout, NULL);
1731 if (ret != 0 || res != 0) {
1735 (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1736 if ((*name) == NULL) {
1740 talloc_free(data.dptr);
1746 get the health status of a db
1748 int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
1749 struct timeval timeout,
1751 uint32_t dbid, TALLOC_CTX *mem_ctx,
1752 const char **reason)
1758 data.dptr = (uint8_t *)&dbid;
1759 data.dsize = sizeof(dbid);
1761 ret = ctdb_control(ctdb, destnode, 0,
1762 CTDB_CONTROL_DB_GET_HEALTH, 0, data,
1763 mem_ctx, &data, &res, &timeout, NULL);
1764 if (ret != 0 || res != 0) {
1768 if (data.dsize == 0) {
1773 (*reason) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1774 if ((*reason) == NULL) {
1778 talloc_free(data.dptr);
1786 int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1787 TALLOC_CTX *mem_ctx, const char *name, bool persistent)
1793 data.dptr = discard_const(name);
1794 data.dsize = strlen(name)+1;
1796 ret = ctdb_control(ctdb, destnode, 0,
1797 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1799 mem_ctx, &data, &res, &timeout, NULL);
1801 if (ret != 0 || res != 0) {
1809 get debug level on a node
1811 int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
1817 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
1818 ctdb, &data, &res, NULL, NULL);
1819 if (ret != 0 || res != 0) {
1822 if (data.dsize != sizeof(int32_t)) {
1823 DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
1824 (unsigned)data.dsize));
1827 *level = *(int32_t *)data.dptr;
1828 talloc_free(data.dptr);
1833 set debug level on a node
1835 int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
1841 data.dptr = (uint8_t *)&level;
1842 data.dsize = sizeof(level);
1844 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data,
1845 NULL, NULL, &res, NULL, NULL);
1846 if (ret != 0 || res != 0) {
1854 get a list of connected nodes
1856 uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
1857 struct timeval timeout,
1858 TALLOC_CTX *mem_ctx,
1859 uint32_t *num_nodes)
1861 struct ctdb_node_map *map=NULL;
1867 ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
1872 nodes = talloc_array(mem_ctx, uint32_t, map->num);
1873 if (nodes == NULL) {
1877 for (i=0;i<map->num;i++) {
1878 if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
1879 nodes[*num_nodes] = map->nodes[i].pnn;
1891 int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
1896 ret = ctdb_control(ctdb, destnode, 0,
1897 CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null,
1898 NULL, NULL, &res, NULL, NULL);
1899 if (ret != 0 || res != 0) {
1900 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
1907 this is the dummy null procedure that all databases support
1909 static int ctdb_null_func(struct ctdb_call_info *call)
1915 this is a plain fetch procedure that all databases support
1917 static int ctdb_fetch_func(struct ctdb_call_info *call)
1919 call->reply_data = &call->record_data;
1924 this is a plain fetch procedure that all databases support
1925 this returns the full record including the ltdb header
1927 static int ctdb_fetch_with_header_func(struct ctdb_call_info *call)
1929 call->reply_data = talloc(call, TDB_DATA);
1930 if (call->reply_data == NULL) {
1933 call->reply_data->dsize = sizeof(struct ctdb_ltdb_header) + call->record_data.dsize;
1934 call->reply_data->dptr = talloc_size(call->reply_data, call->reply_data->dsize);
1935 if (call->reply_data->dptr == NULL) {
1938 memcpy(call->reply_data->dptr, call->header, sizeof(struct ctdb_ltdb_header));
1939 memcpy(&call->reply_data->dptr[sizeof(struct ctdb_ltdb_header)], call->record_data.dptr, call->record_data.dsize);
1945 attach to a specific database - client call
1947 struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name, bool persistent, uint32_t tdb_flags)
1949 struct ctdb_db_context *ctdb_db;
1954 ctdb_db = ctdb_db_handle(ctdb, name);
1959 ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
1960 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
1962 ctdb_db->ctdb = ctdb;
1963 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
1964 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
1966 data.dptr = discard_const(name);
1967 data.dsize = strlen(name)+1;
1969 /* tell ctdb daemon to attach */
1970 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags,
1971 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1972 0, data, ctdb_db, &data, &res, NULL, NULL);
1973 if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
1974 DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
1975 talloc_free(ctdb_db);
1979 ctdb_db->db_id = *(uint32_t *)data.dptr;
1980 talloc_free(data.dptr);
1982 ret = ctdb_ctrl_getdbpath(ctdb, timeval_current_ofs(2, 0), CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
1984 DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
1985 talloc_free(ctdb_db);
1989 tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
1990 if (ctdb->valgrinding) {
1991 tdb_flags |= TDB_NOMMAP;
1993 tdb_flags |= TDB_DISALLOW_NESTING;
1995 ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
1996 if (ctdb_db->ltdb == NULL) {
1997 ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
1998 talloc_free(ctdb_db);
2002 ctdb_db->persistent = persistent;
2004 DLIST_ADD(ctdb->db_list, ctdb_db);
2006 /* add well known functions */
2007 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
2008 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
2009 ctdb_set_call(ctdb_db, ctdb_fetch_with_header_func, CTDB_FETCH_WITH_HEADER_FUNC);
2016 setup a call for a database
2018 int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
2020 struct ctdb_registered_call *call;
2025 struct ctdb_control_set_call c;
2028 /* this is no longer valid with the separate daemon architecture */
2029 c.db_id = ctdb_db->db_id;
2033 data.dptr = (uint8_t *)&c;
2034 data.dsize = sizeof(c);
2036 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_SET_CALL, 0,
2037 data, NULL, NULL, &status, NULL, NULL);
2038 if (ret != 0 || status != 0) {
2039 DEBUG(DEBUG_ERR,("ctdb_set_call failed for call %u\n", id));
2044 /* also register locally */
2045 call = talloc(ctdb_db, struct ctdb_registered_call);
2049 DLIST_ADD(ctdb_db->calls, call);
2054 struct traverse_state {
2057 ctdb_traverse_func fn;
2062 called on each key during a ctdb_traverse
2064 static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p)
2066 struct traverse_state *state = (struct traverse_state *)p;
2067 struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
2070 if (data.dsize < sizeof(uint32_t) ||
2071 d->length != data.dsize) {
2072 DEBUG(DEBUG_ERR,("Bad data size %u in traverse_handler\n", (unsigned)data.dsize));
2077 key.dsize = d->keylen;
2078 key.dptr = &d->data[0];
2079 data.dsize = d->datalen;
2080 data.dptr = &d->data[d->keylen];
2082 if (key.dsize == 0 && data.dsize == 0) {
2083 /* end of traverse */
2088 if (data.dsize == sizeof(struct ctdb_ltdb_header)) {
2089 /* empty records are deleted records in ctdb */
2093 if (state->fn(ctdb, key, data, state->private_data) != 0) {
2102 start a cluster wide traverse, calling the supplied fn on each record
2103 return the number of records traversed, or -1 on error
2105 int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
2108 struct ctdb_traverse_start t;
2111 uint64_t srvid = (getpid() | 0xFLL<<60);
2112 struct traverse_state state;
2116 state.private_data = private_data;
2119 ret = ctdb_client_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
2121 DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
2125 t.db_id = ctdb_db->db_id;
2129 data.dptr = (uint8_t *)&t;
2130 data.dsize = sizeof(t);
2132 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START, 0,
2133 data, NULL, NULL, &status, NULL, NULL);
2134 if (ret != 0 || status != 0) {
2135 DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
2136 ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2140 while (!state.done) {
2141 event_loop_once(ctdb_db->ctdb->ev);
2144 ret = ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2146 DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
2153 #define ISASCII(x) (isprint(x) && !strchr("\"\\", (x)))
2155 called on each key during a catdb
2157 int ctdb_dumpdb_record(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p)
2160 FILE *f = (FILE *)p;
2161 struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
2163 fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
2164 for (i=0;i<key.dsize;i++) {
2165 if (ISASCII(key.dptr[i])) {
2166 fprintf(f, "%c", key.dptr[i]);
2168 fprintf(f, "\\%02X", key.dptr[i]);
2173 fprintf(f, "dmaster: %u\n", h->dmaster);
2174 fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
2175 fprintf(f, "flags: 0x%08x", h->flags);
2176 if (h->flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA) printf(" MIGRATED_WITH_DATA");
2177 if (h->flags & CTDB_REC_FLAG_VACUUM_MIGRATED) printf(" VACUUM_MIGRATED");
2178 if (h->flags & CTDB_REC_FLAG_AUTOMATIC) printf(" AUTOMATIC");
2179 if (h->flags & CTDB_REC_RO_HAVE_DELEGATIONS) printf(" RO_HAVE_DELEGATIONS");
2180 if (h->flags & CTDB_REC_RO_HAVE_READONLY) printf(" RO_HAVE_READONLY");
2181 if (h->flags & CTDB_REC_RO_REVOKING_READONLY) printf(" RO_REVOKING_READONLY");
2182 if (h->flags & CTDB_REC_RO_REVOKE_COMPLETE) printf(" RO_REVOKE_COMPLETE");
2185 fprintf(f, "data(%u) = \"", (unsigned)(data.dsize - sizeof(*h)));
2186 for (i=sizeof(*h);i<data.dsize;i++) {
2187 if (ISASCII(data.dptr[i])) {
2188 fprintf(f, "%c", data.dptr[i]);
2190 fprintf(f, "\\%02X", data.dptr[i]);
2201 convenience function to list all keys to stdout
2203 int ctdb_dump_db(struct ctdb_db_context *ctdb_db, FILE *f)
2205 return ctdb_traverse(ctdb_db, ctdb_dumpdb_record, f);
2209 get the pid of a ctdb daemon
2211 int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
2216 ret = ctdb_control(ctdb, destnode, 0,
2217 CTDB_CONTROL_GET_PID, 0, tdb_null,
2218 NULL, NULL, &res, &timeout, NULL);
2220 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
2231 async freeze send control
2233 struct ctdb_client_control_state *
2234 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
2236 return ctdb_control_send(ctdb, destnode, priority,
2237 CTDB_CONTROL_FREEZE, 0, tdb_null,
2238 mem_ctx, &timeout, NULL);
2242 async freeze recv control
2244 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
2249 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
2250 if ( (ret != 0) || (res != 0) ){
2251 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
2259 freeze databases of a certain priority
2261 int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2263 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2264 struct ctdb_client_control_state *state;
2267 state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
2268 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
2269 talloc_free(tmp_ctx);
2274 /* Freeze all databases */
2275 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2279 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
2280 if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
2288 thaw databases of a certain priority
2290 int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2295 ret = ctdb_control(ctdb, destnode, priority,
2296 CTDB_CONTROL_THAW, 0, tdb_null,
2297 NULL, NULL, &res, &timeout, NULL);
2298 if (ret != 0 || res != 0) {
2299 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
2306 /* thaw all databases */
2307 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2309 return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
2313 get pnn of a node, or -1
2315 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2320 ret = ctdb_control(ctdb, destnode, 0,
2321 CTDB_CONTROL_GET_PNN, 0, tdb_null,
2322 NULL, NULL, &res, &timeout, NULL);
2324 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
2332 get the monitoring mode of a remote node
2334 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
2339 ret = ctdb_control(ctdb, destnode, 0,
2340 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
2341 NULL, NULL, &res, &timeout, NULL);
2343 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
2354 set the monitoring mode of a remote node to active
2356 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2361 ret = ctdb_control(ctdb, destnode, 0,
2362 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
2363 NULL, NULL,NULL, &timeout, NULL);
2365 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
2375 set the monitoring mode of a remote node to disable
2377 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2382 ret = ctdb_control(ctdb, destnode, 0,
2383 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
2384 NULL, NULL, NULL, &timeout, NULL);
2386 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
2398 sent to a node to make it take over an ip address
2400 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
2401 uint32_t destnode, struct ctdb_public_ip *ip)
2404 struct ctdb_public_ipv4 ipv4;
2408 if (ip->addr.sa.sa_family == AF_INET) {
2410 ipv4.sin = ip->addr.ip;
2412 data.dsize = sizeof(ipv4);
2413 data.dptr = (uint8_t *)&ipv4;
2415 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
2416 NULL, &res, &timeout, NULL);
2418 data.dsize = sizeof(*ip);
2419 data.dptr = (uint8_t *)ip;
2421 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
2422 NULL, &res, &timeout, NULL);
2425 if (ret != 0 || res != 0) {
2426 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
2435 sent to a node to make it release an ip address
2437 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
2438 uint32_t destnode, struct ctdb_public_ip *ip)
2441 struct ctdb_public_ipv4 ipv4;
2445 if (ip->addr.sa.sa_family == AF_INET) {
2447 ipv4.sin = ip->addr.ip;
2449 data.dsize = sizeof(ipv4);
2450 data.dptr = (uint8_t *)&ipv4;
2452 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
2453 NULL, &res, &timeout, NULL);
2455 data.dsize = sizeof(*ip);
2456 data.dptr = (uint8_t *)ip;
2458 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
2459 NULL, &res, &timeout, NULL);
2462 if (ret != 0 || res != 0) {
2463 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
2474 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
2475 struct timeval timeout,
2477 const char *name, uint32_t *value)
2479 struct ctdb_control_get_tunable *t;
2480 TDB_DATA data, outdata;
2484 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
2485 data.dptr = talloc_size(ctdb, data.dsize);
2486 CTDB_NO_MEMORY(ctdb, data.dptr);
2488 t = (struct ctdb_control_get_tunable *)data.dptr;
2489 t->length = strlen(name)+1;
2490 memcpy(t->name, name, t->length);
2492 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
2493 &outdata, &res, &timeout, NULL);
2494 talloc_free(data.dptr);
2495 if (ret != 0 || res != 0) {
2496 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
2500 if (outdata.dsize != sizeof(uint32_t)) {
2501 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
2502 talloc_free(outdata.dptr);
2506 *value = *(uint32_t *)outdata.dptr;
2507 talloc_free(outdata.dptr);
2515 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
2516 struct timeval timeout,
2518 const char *name, uint32_t value)
2520 struct ctdb_control_set_tunable *t;
2525 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
2526 data.dptr = talloc_size(ctdb, data.dsize);
2527 CTDB_NO_MEMORY(ctdb, data.dptr);
2529 t = (struct ctdb_control_set_tunable *)data.dptr;
2530 t->length = strlen(name)+1;
2531 memcpy(t->name, name, t->length);
2534 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
2535 NULL, &res, &timeout, NULL);
2536 talloc_free(data.dptr);
2537 if (ret != 0 || res != 0) {
2538 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
2548 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
2549 struct timeval timeout,
2551 TALLOC_CTX *mem_ctx,
2552 const char ***list, uint32_t *count)
2557 struct ctdb_control_list_tunable *t;
2560 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
2561 mem_ctx, &outdata, &res, &timeout, NULL);
2562 if (ret != 0 || res != 0) {
2563 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
2567 t = (struct ctdb_control_list_tunable *)outdata.dptr;
2568 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
2569 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
2570 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
2571 talloc_free(outdata.dptr);
2575 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
2576 CTDB_NO_MEMORY(ctdb, p);
2578 talloc_free(outdata.dptr);
2583 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
2584 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
2585 CTDB_NO_MEMORY(ctdb, *list);
2586 (*list)[*count] = talloc_strdup(*list, s);
2587 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
2597 int ctdb_ctrl_get_public_ips_flags(struct ctdb_context *ctdb,
2598 struct timeval timeout, uint32_t destnode,
2599 TALLOC_CTX *mem_ctx,
2601 struct ctdb_all_public_ips **ips)
2607 ret = ctdb_control(ctdb, destnode, 0,
2608 CTDB_CONTROL_GET_PUBLIC_IPS, flags, tdb_null,
2609 mem_ctx, &outdata, &res, &timeout, NULL);
2610 if (ret == 0 && res == -1) {
2611 DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
2612 return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
2614 if (ret != 0 || res != 0) {
2615 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
2619 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
2620 talloc_free(outdata.dptr);
2625 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
2626 struct timeval timeout, uint32_t destnode,
2627 TALLOC_CTX *mem_ctx,
2628 struct ctdb_all_public_ips **ips)
2630 return ctdb_ctrl_get_public_ips_flags(ctdb, timeout,
2635 int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
2636 struct timeval timeout, uint32_t destnode,
2637 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2642 struct ctdb_all_public_ipsv4 *ipsv4;
2644 ret = ctdb_control(ctdb, destnode, 0,
2645 CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null,
2646 mem_ctx, &outdata, &res, &timeout, NULL);
2647 if (ret != 0 || res != 0) {
2648 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
2652 ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
2653 len = offsetof(struct ctdb_all_public_ips, ips) +
2654 ipsv4->num*sizeof(struct ctdb_public_ip);
2655 *ips = talloc_zero_size(mem_ctx, len);
2656 CTDB_NO_MEMORY(ctdb, *ips);
2657 (*ips)->num = ipsv4->num;
2658 for (i=0; i<ipsv4->num; i++) {
2659 (*ips)->ips[i].pnn = ipsv4->ips[i].pnn;
2660 (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
2663 talloc_free(outdata.dptr);
2668 int ctdb_ctrl_get_public_ip_info(struct ctdb_context *ctdb,
2669 struct timeval timeout, uint32_t destnode,
2670 TALLOC_CTX *mem_ctx,
2671 const ctdb_sock_addr *addr,
2672 struct ctdb_control_public_ip_info **_info)
2678 struct ctdb_control_public_ip_info *info;
2682 indata.dptr = discard_const_p(uint8_t, addr);
2683 indata.dsize = sizeof(*addr);
2685 ret = ctdb_control(ctdb, destnode, 0,
2686 CTDB_CONTROL_GET_PUBLIC_IP_INFO, 0, indata,
2687 mem_ctx, &outdata, &res, &timeout, NULL);
2688 if (ret != 0 || res != 0) {
2689 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2690 "failed ret:%d res:%d\n",
2695 len = offsetof(struct ctdb_control_public_ip_info, ifaces);
2696 if (len > outdata.dsize) {
2697 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2698 "returned invalid data with size %u > %u\n",
2699 (unsigned int)outdata.dsize,
2700 (unsigned int)len));
2701 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2705 info = (struct ctdb_control_public_ip_info *)outdata.dptr;
2706 len += info->num*sizeof(struct ctdb_control_iface_info);
2708 if (len > outdata.dsize) {
2709 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2710 "returned invalid data with size %u > %u\n",
2711 (unsigned int)outdata.dsize,
2712 (unsigned int)len));
2713 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2717 /* make sure we null terminate the returned strings */
2718 for (i=0; i < info->num; i++) {
2719 info->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2722 *_info = (struct ctdb_control_public_ip_info *)talloc_memdup(mem_ctx,
2725 talloc_free(outdata.dptr);
2726 if (*_info == NULL) {
2727 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2728 "talloc_memdup size %u failed\n",
2729 (unsigned int)outdata.dsize));
2736 int ctdb_ctrl_get_ifaces(struct ctdb_context *ctdb,
2737 struct timeval timeout, uint32_t destnode,
2738 TALLOC_CTX *mem_ctx,
2739 struct ctdb_control_get_ifaces **_ifaces)
2744 struct ctdb_control_get_ifaces *ifaces;
2748 ret = ctdb_control(ctdb, destnode, 0,
2749 CTDB_CONTROL_GET_IFACES, 0, tdb_null,
2750 mem_ctx, &outdata, &res, &timeout, NULL);
2751 if (ret != 0 || res != 0) {
2752 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2753 "failed ret:%d res:%d\n",
2758 len = offsetof(struct ctdb_control_get_ifaces, ifaces);
2759 if (len > outdata.dsize) {
2760 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2761 "returned invalid data with size %u > %u\n",
2762 (unsigned int)outdata.dsize,
2763 (unsigned int)len));
2764 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2768 ifaces = (struct ctdb_control_get_ifaces *)outdata.dptr;
2769 len += ifaces->num*sizeof(struct ctdb_control_iface_info);
2771 if (len > outdata.dsize) {
2772 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2773 "returned invalid data with size %u > %u\n",
2774 (unsigned int)outdata.dsize,
2775 (unsigned int)len));
2776 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2780 /* make sure we null terminate the returned strings */
2781 for (i=0; i < ifaces->num; i++) {
2782 ifaces->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2785 *_ifaces = (struct ctdb_control_get_ifaces *)talloc_memdup(mem_ctx,
2788 talloc_free(outdata.dptr);
2789 if (*_ifaces == NULL) {
2790 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2791 "talloc_memdup size %u failed\n",
2792 (unsigned int)outdata.dsize));
2799 int ctdb_ctrl_set_iface_link(struct ctdb_context *ctdb,
2800 struct timeval timeout, uint32_t destnode,
2801 TALLOC_CTX *mem_ctx,
2802 const struct ctdb_control_iface_info *info)
2808 indata.dptr = discard_const_p(uint8_t, info);
2809 indata.dsize = sizeof(*info);
2811 ret = ctdb_control(ctdb, destnode, 0,
2812 CTDB_CONTROL_SET_IFACE_LINK_STATE, 0, indata,
2813 mem_ctx, NULL, &res, &timeout, NULL);
2814 if (ret != 0 || res != 0) {
2815 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set iface link "
2816 "failed ret:%d res:%d\n",
2825 set/clear the permanent disabled bit on a remote node
2827 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
2828 uint32_t set, uint32_t clear)
2832 struct ctdb_node_map *nodemap=NULL;
2833 struct ctdb_node_flag_change c;
2834 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2839 /* find the recovery master */
2840 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
2842 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
2843 talloc_free(tmp_ctx);
2848 /* read the node flags from the recmaster */
2849 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
2851 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
2852 talloc_free(tmp_ctx);
2855 if (destnode >= nodemap->num) {
2856 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
2857 talloc_free(tmp_ctx);
2862 c.old_flags = nodemap->nodes[destnode].flags;
2863 c.new_flags = c.old_flags;
2865 c.new_flags &= ~clear;
2867 data.dsize = sizeof(c);
2868 data.dptr = (unsigned char *)&c;
2870 /* send the flags update to all connected nodes */
2871 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
2873 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
2875 timeout, false, data,
2878 DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
2880 talloc_free(tmp_ctx);
2884 talloc_free(tmp_ctx);
2892 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
2893 struct timeval timeout,
2895 struct ctdb_tunable *tunables)
2901 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
2902 &outdata, &res, &timeout, NULL);
2903 if (ret != 0 || res != 0) {
2904 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
2908 if (outdata.dsize != sizeof(*tunables)) {
2909 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
2910 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
2914 *tunables = *(struct ctdb_tunable *)outdata.dptr;
2915 talloc_free(outdata.dptr);
2920 add a public address to a node
2922 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
2923 struct timeval timeout,
2925 struct ctdb_control_ip_iface *pub)
2931 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2932 data.dptr = (unsigned char *)pub;
2934 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
2935 NULL, &res, &timeout, NULL);
2936 if (ret != 0 || res != 0) {
2937 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
2945 delete a public address from a node
2947 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
2948 struct timeval timeout,
2950 struct ctdb_control_ip_iface *pub)
2956 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2957 data.dptr = (unsigned char *)pub;
2959 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
2960 NULL, &res, &timeout, NULL);
2961 if (ret != 0 || res != 0) {
2962 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
2970 kill a tcp connection
2972 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
2973 struct timeval timeout,
2975 struct ctdb_control_killtcp *killtcp)
2981 data.dsize = sizeof(struct ctdb_control_killtcp);
2982 data.dptr = (unsigned char *)killtcp;
2984 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
2985 NULL, &res, &timeout, NULL);
2986 if (ret != 0 || res != 0) {
2987 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
2997 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
2998 struct timeval timeout,
3000 ctdb_sock_addr *addr,
3006 struct ctdb_control_gratious_arp *gratious_arp;
3007 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3010 len = strlen(ifname)+1;
3011 gratious_arp = talloc_size(tmp_ctx,
3012 offsetof(struct ctdb_control_gratious_arp, iface) + len);
3013 CTDB_NO_MEMORY(ctdb, gratious_arp);
3015 gratious_arp->addr = *addr;
3016 gratious_arp->len = len;
3017 memcpy(&gratious_arp->iface[0], ifname, len);
3020 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
3021 data.dptr = (unsigned char *)gratious_arp;
3023 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
3024 NULL, &res, &timeout, NULL);
3025 if (ret != 0 || res != 0) {
3026 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
3027 talloc_free(tmp_ctx);
3031 talloc_free(tmp_ctx);
3036 get a list of all tcp tickles that a node knows about for a particular vnn
3038 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
3039 struct timeval timeout, uint32_t destnode,
3040 TALLOC_CTX *mem_ctx,
3041 ctdb_sock_addr *addr,
3042 struct ctdb_control_tcp_tickle_list **list)
3045 TDB_DATA data, outdata;
3048 data.dptr = (uint8_t*)addr;
3049 data.dsize = sizeof(ctdb_sock_addr);
3051 ret = ctdb_control(ctdb, destnode, 0,
3052 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
3053 mem_ctx, &outdata, &status, NULL, NULL);
3054 if (ret != 0 || status != 0) {
3055 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
3059 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
3065 register a server id
3067 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
3068 struct timeval timeout,
3069 struct ctdb_server_id *id)
3075 data.dsize = sizeof(struct ctdb_server_id);
3076 data.dptr = (unsigned char *)id;
3078 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3079 CTDB_CONTROL_REGISTER_SERVER_ID,
3081 NULL, &res, &timeout, NULL);
3082 if (ret != 0 || res != 0) {
3083 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
3091 unregister a server id
3093 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
3094 struct timeval timeout,
3095 struct ctdb_server_id *id)
3101 data.dsize = sizeof(struct ctdb_server_id);
3102 data.dptr = (unsigned char *)id;
3104 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3105 CTDB_CONTROL_UNREGISTER_SERVER_ID,
3107 NULL, &res, &timeout, NULL);
3108 if (ret != 0 || res != 0) {
3109 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
3118 check if a server id exists
3120 if a server id does exist, return *status == 1, otherwise *status == 0
3122 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
3123 struct timeval timeout,
3125 struct ctdb_server_id *id,
3132 data.dsize = sizeof(struct ctdb_server_id);
3133 data.dptr = (unsigned char *)id;
3135 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
3137 NULL, &res, &timeout, NULL);
3139 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
3153 get the list of server ids that are registered on a node
3155 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
3156 TALLOC_CTX *mem_ctx,
3157 struct timeval timeout, uint32_t destnode,
3158 struct ctdb_server_id_list **svid_list)
3164 ret = ctdb_control(ctdb, destnode, 0,
3165 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
3166 mem_ctx, &outdata, &res, &timeout, NULL);
3167 if (ret != 0 || res != 0) {
3168 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
3172 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
3178 initialise the ctdb daemon for client applications
3180 NOTE: In current code the daemon does not fork. This is for testing purposes only
3181 and to simplify the code.
3183 struct ctdb_context *ctdb_init(struct event_context *ev)
3186 struct ctdb_context *ctdb;
3188 ctdb = talloc_zero(ev, struct ctdb_context);
3190 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
3194 ctdb->idr = idr_init(ctdb);
3195 /* Wrap early to exercise code. */
3196 ctdb->lastid = INT_MAX-200;
3197 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
3199 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
3201 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
3206 ctdb->statistics.statistics_start_time = timeval_current();
3215 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
3217 ctdb->flags |= flags;
3221 setup the local socket name
3223 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
3225 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
3226 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
3231 const char *ctdb_get_socketname(struct ctdb_context *ctdb)
3233 return ctdb->daemon.name;
3237 return the pnn of this node
3239 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
3246 get the uptime of a remote node
3248 struct ctdb_client_control_state *
3249 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3251 return ctdb_control_send(ctdb, destnode, 0,
3252 CTDB_CONTROL_UPTIME, 0, tdb_null,
3253 mem_ctx, &timeout, NULL);
3256 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
3262 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3263 if (ret != 0 || res != 0) {
3264 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
3268 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
3273 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
3275 struct ctdb_client_control_state *state;
3277 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
3278 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
3282 send a control to execute the "recovered" event script on a node
3284 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3289 ret = ctdb_control(ctdb, destnode, 0,
3290 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
3291 NULL, NULL, &status, &timeout, NULL);
3292 if (ret != 0 || status != 0) {
3293 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
3301 callback for the async helpers used when sending the same control
3302 to multiple nodes in parallell.
3304 static void async_callback(struct ctdb_client_control_state *state)
3306 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
3307 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
3311 uint32_t destnode = state->c->hdr.destnode;
3313 /* one more node has responded with recmode data */
3316 /* if we failed to push the db, then return an error and let
3317 the main loop try again.
3319 if (state->state != CTDB_CONTROL_DONE) {
3320 if ( !data->dont_log_errors) {
3321 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
3324 if (data->fail_callback) {
3325 data->fail_callback(ctdb, destnode, res, outdata,
3326 data->callback_data);
3331 state->async.fn = NULL;
3333 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
3334 if ((ret != 0) || (res != 0)) {
3335 if ( !data->dont_log_errors) {
3336 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
3339 if (data->fail_callback) {
3340 data->fail_callback(ctdb, destnode, res, outdata,
3341 data->callback_data);
3344 if ((ret == 0) && (data->callback != NULL)) {
3345 data->callback(ctdb, destnode, res, outdata,
3346 data->callback_data);
3351 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
3353 /* set up the callback functions */
3354 state->async.fn = async_callback;
3355 state->async.private_data = data;
3357 /* one more control to wait for to complete */
3362 /* wait for up to the maximum number of seconds allowed
3363 or until all nodes we expect a response from has replied
3365 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
3367 while (data->count > 0) {
3368 event_loop_once(ctdb->ev);
3370 if (data->fail_count != 0) {
3371 if (!data->dont_log_errors) {
3372 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
3382 perform a simple control on the listed nodes
3383 The control cannot return data
3385 int ctdb_client_async_control(struct ctdb_context *ctdb,
3386 enum ctdb_controls opcode,
3389 struct timeval timeout,
3390 bool dont_log_errors,
3392 client_async_callback client_callback,
3393 client_async_callback fail_callback,
3394 void *callback_data)
3396 struct client_async_data *async_data;
3397 struct ctdb_client_control_state *state;
3400 async_data = talloc_zero(ctdb, struct client_async_data);
3401 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
3402 async_data->dont_log_errors = dont_log_errors;
3403 async_data->callback = client_callback;
3404 async_data->fail_callback = fail_callback;
3405 async_data->callback_data = callback_data;
3406 async_data->opcode = opcode;
3408 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
3410 /* loop over all nodes and send an async control to each of them */
3411 for (j=0; j<num_nodes; j++) {
3412 uint32_t pnn = nodes[j];
3414 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
3415 0, data, async_data, &timeout, NULL);
3416 if (state == NULL) {
3417 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
3418 talloc_free(async_data);
3422 ctdb_client_async_add(async_data, state);
3425 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
3426 talloc_free(async_data);
3430 talloc_free(async_data);
3434 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
3435 struct ctdb_vnn_map *vnn_map,
3436 TALLOC_CTX *mem_ctx,
3439 int i, j, num_nodes;
3442 for (i=num_nodes=0;i<vnn_map->size;i++) {
3443 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3449 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3450 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3452 for (i=j=0;i<vnn_map->size;i++) {
3453 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3456 nodes[j++] = vnn_map->map[i];
3462 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
3463 struct ctdb_node_map *node_map,
3464 TALLOC_CTX *mem_ctx,
3467 int i, j, num_nodes;
3470 for (i=num_nodes=0;i<node_map->num;i++) {
3471 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3474 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3480 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3481 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3483 for (i=j=0;i<node_map->num;i++) {
3484 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3487 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3490 nodes[j++] = node_map->nodes[i].pnn;
3496 uint32_t *list_of_active_nodes_except_pnn(struct ctdb_context *ctdb,
3497 struct ctdb_node_map *node_map,
3498 TALLOC_CTX *mem_ctx,
3501 int i, j, num_nodes;
3504 for (i=num_nodes=0;i<node_map->num;i++) {
3505 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3508 if (node_map->nodes[i].pnn == pnn) {
3514 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3515 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3517 for (i=j=0;i<node_map->num;i++) {
3518 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3521 if (node_map->nodes[i].pnn == pnn) {
3524 nodes[j++] = node_map->nodes[i].pnn;
3530 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
3531 struct ctdb_node_map *node_map,
3532 TALLOC_CTX *mem_ctx,
3535 int i, j, num_nodes;
3538 for (i=num_nodes=0;i<node_map->num;i++) {
3539 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3542 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3548 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3549 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3551 for (i=j=0;i<node_map->num;i++) {
3552 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3555 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3558 nodes[j++] = node_map->nodes[i].pnn;
3565 this is used to test if a pnn lock exists and if it exists will return
3566 the number of connections that pnn has reported or -1 if that recovery
3567 daemon is not running.
3570 ctdb_read_pnn_lock(int fd, int32_t pnn)
3575 lock.l_type = F_WRLCK;
3576 lock.l_whence = SEEK_SET;
3581 if (fcntl(fd, F_GETLK, &lock) != 0) {
3582 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3586 if (lock.l_type == F_UNLCK) {
3590 if (pread(fd, &c, 1, pnn) == -1) {
3591 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3599 get capabilities of a remote node
3601 struct ctdb_client_control_state *
3602 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3604 return ctdb_control_send(ctdb, destnode, 0,
3605 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3606 mem_ctx, &timeout, NULL);
3609 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3615 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3616 if ( (ret != 0) || (res != 0) ) {
3617 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3622 *capabilities = *((uint32_t *)outdata.dptr);
3628 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3630 struct ctdb_client_control_state *state;
3631 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3634 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3635 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3636 talloc_free(tmp_ctx);
3641 * check whether a transaction is active on a given db on a given node
3643 int32_t ctdb_ctrl_transaction_active(struct ctdb_context *ctdb,
3651 indata.dptr = (uint8_t *)&db_id;
3652 indata.dsize = sizeof(db_id);
3654 ret = ctdb_control(ctdb, destnode, 0,
3655 CTDB_CONTROL_TRANS2_ACTIVE,
3656 0, indata, NULL, NULL, &status,
3660 DEBUG(DEBUG_ERR, (__location__ " ctdb control for transaction_active failed\n"));
3668 struct ctdb_transaction_handle {
3669 struct ctdb_db_context *ctdb_db;
3672 * we store the reads and writes done under a transaction:
3673 * - one list stores both reads and writes (m_all),
3674 * - the other just writes (m_write)
3676 struct ctdb_marshall_buffer *m_all;
3677 struct ctdb_marshall_buffer *m_write;
3680 /* start a transaction on a database */
3681 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
3683 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3687 /* start a transaction on a database */
3688 static int ctdb_transaction_fetch_start(struct ctdb_transaction_handle *h)
3690 struct ctdb_record_handle *rh;
3693 struct ctdb_ltdb_header header;
3694 TALLOC_CTX *tmp_ctx;
3695 const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
3697 struct ctdb_db_context *ctdb_db = h->ctdb_db;
3701 key.dptr = discard_const(keyname);
3702 key.dsize = strlen(keyname);
3704 if (!ctdb_db->persistent) {
3705 DEBUG(DEBUG_ERR,(__location__ " Attempted transaction on non-persistent database\n"));
3710 tmp_ctx = talloc_new(h);
3712 rh = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, NULL);
3714 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch_lock database\n"));
3715 talloc_free(tmp_ctx);
3719 status = ctdb_ctrl_transaction_active(ctdb_db->ctdb,
3723 unsigned long int usec = (1000 + random()) % 100000;
3724 DEBUG(DEBUG_DEBUG, (__location__ " transaction is active "
3725 "on db_id[0x%08x]. waiting for %lu "
3727 ctdb_db->db_id, usec));
3728 talloc_free(tmp_ctx);
3734 * store the pid in the database:
3735 * it is not enough that the node is dmaster...
3738 data.dptr = (unsigned char *)&pid;
3739 data.dsize = sizeof(pid_t);
3741 rh->header.dmaster = ctdb_db->ctdb->pnn;
3742 ret = ctdb_ltdb_store(ctdb_db, key, &(rh->header), data);
3744 DEBUG(DEBUG_ERR, (__location__ " Failed to store pid in "
3745 "transaction record\n"));
3746 talloc_free(tmp_ctx);
3752 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3754 DEBUG(DEBUG_ERR,(__location__ " Failed to start tdb transaction\n"));
3755 talloc_free(tmp_ctx);
3759 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, &data);
3761 DEBUG(DEBUG_ERR,(__location__ " Failed to re-fetch transaction "
3762 "lock record inside transaction\n"));
3763 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3764 talloc_free(tmp_ctx);
3768 if (header.dmaster != ctdb_db->ctdb->pnn) {
3769 DEBUG(DEBUG_DEBUG,(__location__ " not dmaster any more on "
3770 "transaction lock record\n"));
3771 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3772 talloc_free(tmp_ctx);
3776 if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
3777 DEBUG(DEBUG_DEBUG, (__location__ " my pid is not stored in "
3778 "the transaction lock record\n"));
3779 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3780 talloc_free(tmp_ctx);
3784 talloc_free(tmp_ctx);
3790 /* start a transaction on a database */
3791 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
3792 TALLOC_CTX *mem_ctx)
3794 struct ctdb_transaction_handle *h;
3797 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
3799 DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
3803 h->ctdb_db = ctdb_db;
3805 ret = ctdb_transaction_fetch_start(h);
3811 talloc_set_destructor(h, ctdb_transaction_destructor);
3819 fetch a record inside a transaction
3821 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
3822 TALLOC_CTX *mem_ctx,
3823 TDB_DATA key, TDB_DATA *data)
3825 struct ctdb_ltdb_header header;
3828 ZERO_STRUCT(header);
3830 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
3831 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3832 /* record doesn't exist yet */
3841 if (!h->in_replay) {
3842 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
3843 if (h->m_all == NULL) {
3844 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3853 stores a record inside a transaction
3855 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
3856 TDB_DATA key, TDB_DATA data)
3858 TALLOC_CTX *tmp_ctx = talloc_new(h);
3859 struct ctdb_ltdb_header header;
3863 ZERO_STRUCT(header);
3865 /* we need the header so we can update the RSN */
3866 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
3867 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3868 /* the record doesn't exist - create one with us as dmaster.
3869 This is only safe because we are in a transaction and this
3870 is a persistent database */
3871 ZERO_STRUCT(header);
3872 } else if (ret != 0) {
3873 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
3874 talloc_free(tmp_ctx);
3878 if (data.dsize == olddata.dsize &&
3879 memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
3880 /* save writing the same data */
3881 talloc_free(tmp_ctx);
3885 header.dmaster = h->ctdb_db->ctdb->pnn;
3888 if (!h->in_replay) {
3889 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
3890 if (h->m_all == NULL) {
3891 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3892 talloc_free(tmp_ctx);
3897 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
3898 if (h->m_write == NULL) {
3899 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3900 talloc_free(tmp_ctx);
3904 ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
3906 talloc_free(tmp_ctx);
3912 replay a transaction
3914 static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
3917 struct ctdb_rec_data *rec = NULL;
3919 h->in_replay = true;
3920 talloc_free(h->m_write);
3923 ret = ctdb_transaction_fetch_start(h);
3928 for (i=0;i<h->m_all->count;i++) {
3931 rec = ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
3933 DEBUG(DEBUG_ERR, (__location__ " Out of records in ctdb_replay_transaction?\n"));
3937 if (rec->reqid == 0) {
3939 if (ctdb_transaction_store(h, key, data) != 0) {
3944 TALLOC_CTX *tmp_ctx = talloc_new(h);
3946 if (ctdb_transaction_fetch(h, tmp_ctx, key, &data2) != 0) {
3947 talloc_free(tmp_ctx);
3950 if (data2.dsize != data.dsize ||
3951 memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
3952 /* the record has changed on us - we have to give up */
3953 talloc_free(tmp_ctx);
3956 talloc_free(tmp_ctx);
3963 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3969 commit a transaction
3971 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
3975 struct ctdb_context *ctdb = h->ctdb_db->ctdb;
3976 struct timeval timeout;
3977 enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
3979 talloc_set_destructor(h, NULL);
3981 /* our commit strategy is quite complex.
3983 - we first try to commit the changes to all other nodes
3985 - if that works, then we commit locally and we are done
3987 - if a commit on another node fails, then we need to cancel
3988 the transaction, then restart the transaction (thus
3989 opening a window of time for a pending recovery to
3990 complete), then replay the transaction, checking all the
3991 reads and writes (checking that reads give the same data,
3992 and writes succeed). Then we retry the transaction to the
3997 if (h->m_write == NULL) {
3998 /* no changes were made */
3999 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
4004 /* tell ctdbd to commit to the other nodes */
4005 timeout = timeval_current_ofs(1, 0);
4006 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4007 retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY, 0,
4008 ctdb_marshall_finish(h->m_write), NULL, NULL, &status,
4010 if (ret != 0 || status != 0) {
4011 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
4012 DEBUG(DEBUG_NOTICE, (__location__ " transaction commit%s failed"
4013 ", retrying after 1 second...\n",
4014 (retries==0)?"":"retry "));
4018 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4020 /* work out what error code we will give if we
4021 have to fail the operation */
4022 switch ((enum ctdb_trans2_commit_error)status) {
4023 case CTDB_TRANS2_COMMIT_SUCCESS:
4024 case CTDB_TRANS2_COMMIT_SOMEFAIL:
4025 case CTDB_TRANS2_COMMIT_TIMEOUT:
4026 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4028 case CTDB_TRANS2_COMMIT_ALLFAIL:
4029 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
4034 if (++retries == 100) {
4035 DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
4036 h->ctdb_db->db_id, retries, (unsigned)failure_control));
4037 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4038 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4039 tdb_null, NULL, NULL, NULL, NULL, NULL);
4044 if (ctdb_replay_transaction(h) != 0) {
4045 DEBUG(DEBUG_ERR, (__location__ " Failed to replay "
4046 "transaction on db 0x%08x, "
4047 "failure control =%u\n",
4049 (unsigned)failure_control));
4050 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4051 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4052 tdb_null, NULL, NULL, NULL, NULL, NULL);
4058 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4061 /* do the real commit locally */
4062 ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
4064 DEBUG(DEBUG_ERR, (__location__ " Failed to commit transaction "
4065 "on db id 0x%08x locally, "
4066 "failure_control=%u\n",
4068 (unsigned)failure_control));
4069 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4070 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4071 tdb_null, NULL, NULL, NULL, NULL, NULL);
4076 /* tell ctdbd that we are finished with our local commit */
4077 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4078 CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
4079 tdb_null, NULL, NULL, NULL, NULL, NULL);
4085 recovery daemon ping to main daemon
4087 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
4092 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
4093 ctdb, NULL, &res, NULL, NULL);
4094 if (ret != 0 || res != 0) {
4095 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
4102 /* when forking the main daemon and the child process needs to connect back
4103 * to the daemon as a client process, this function can be used to change
4104 * the ctdb context from daemon into client mode
4106 int switch_from_server_to_client(struct ctdb_context *ctdb, const char *fmt, ...)
4111 /* Add extra information so we can identify this in the logs */
4113 debug_extra = talloc_strdup_append(talloc_vasprintf(NULL, fmt, ap), ":");
4116 /* shutdown the transport */
4117 if (ctdb->methods) {
4118 ctdb->methods->shutdown(ctdb);
4121 /* get a new event context */
4122 talloc_free(ctdb->ev);
4123 ctdb->ev = event_context_init(ctdb);
4124 tevent_loop_allow_nesting(ctdb->ev);
4126 close(ctdb->daemon.sd);
4127 ctdb->daemon.sd = -1;
4129 /* the client does not need to be realtime */
4130 if (ctdb->do_setsched) {
4131 ctdb_restore_scheduler(ctdb);
4134 /* initialise ctdb */
4135 ret = ctdb_socket_connect(ctdb);
4137 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
4145 get the status of running the monitor eventscripts: NULL means never run.
4147 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
4148 struct timeval timeout, uint32_t destnode,
4149 TALLOC_CTX *mem_ctx, enum ctdb_eventscript_call type,
4150 struct ctdb_scripts_wire **script_status)
4153 TDB_DATA outdata, indata;
4155 uint32_t uinttype = type;
4157 indata.dptr = (uint8_t *)&uinttype;
4158 indata.dsize = sizeof(uinttype);
4160 ret = ctdb_control(ctdb, destnode, 0,
4161 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, indata,
4162 mem_ctx, &outdata, &res, &timeout, NULL);
4163 if (ret != 0 || res != 0) {
4164 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
4168 if (outdata.dsize == 0) {
4169 *script_status = NULL;
4171 *script_status = (struct ctdb_scripts_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4172 talloc_free(outdata.dptr);
4179 tell the main daemon how long it took to lock the reclock file
4181 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
4187 data.dptr = (uint8_t *)&latency;
4188 data.dsize = sizeof(latency);
4190 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
4191 ctdb, NULL, &res, NULL, NULL);
4192 if (ret != 0 || res != 0) {
4193 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
4201 get the name of the reclock file
4203 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
4204 uint32_t destnode, TALLOC_CTX *mem_ctx,
4211 ret = ctdb_control(ctdb, destnode, 0,
4212 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
4213 mem_ctx, &data, &res, &timeout, NULL);
4214 if (ret != 0 || res != 0) {
4218 if (data.dsize == 0) {
4221 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
4223 talloc_free(data.dptr);
4229 set the reclock filename for a node
4231 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
4237 if (reclock == NULL) {
4241 data.dsize = strlen(reclock) + 1;
4242 data.dptr = discard_const(reclock);
4245 ret = ctdb_control(ctdb, destnode, 0,
4246 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
4247 NULL, NULL, &res, &timeout, NULL);
4248 if (ret != 0 || res != 0) {
4249 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
4259 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4264 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
4265 ctdb, NULL, &res, &timeout, NULL);
4266 if (ret != 0 || res != 0) {
4267 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
4277 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4281 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
4282 ctdb, NULL, NULL, &timeout, NULL);
4284 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
4292 set the natgw state for a node
4294 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
4300 data.dsize = sizeof(natgwstate);
4301 data.dptr = (uint8_t *)&natgwstate;
4303 ret = ctdb_control(ctdb, destnode, 0,
4304 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
4305 NULL, NULL, &res, &timeout, NULL);
4306 if (ret != 0 || res != 0) {
4307 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
4315 set the lmaster role for a node
4317 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
4323 data.dsize = sizeof(lmasterrole);
4324 data.dptr = (uint8_t *)&lmasterrole;
4326 ret = ctdb_control(ctdb, destnode, 0,
4327 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
4328 NULL, NULL, &res, &timeout, NULL);
4329 if (ret != 0 || res != 0) {
4330 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
4338 set the recmaster role for a node
4340 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
4346 data.dsize = sizeof(recmasterrole);
4347 data.dptr = (uint8_t *)&recmasterrole;
4349 ret = ctdb_control(ctdb, destnode, 0,
4350 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
4351 NULL, NULL, &res, &timeout, NULL);
4352 if (ret != 0 || res != 0) {
4353 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
4360 /* enable an eventscript
4362 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4368 data.dsize = strlen(script) + 1;
4369 data.dptr = discard_const(script);
4371 ret = ctdb_control(ctdb, destnode, 0,
4372 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
4373 NULL, NULL, &res, &timeout, NULL);
4374 if (ret != 0 || res != 0) {
4375 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
4382 /* disable an eventscript
4384 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4390 data.dsize = strlen(script) + 1;
4391 data.dptr = discard_const(script);
4393 ret = ctdb_control(ctdb, destnode, 0,
4394 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
4395 NULL, NULL, &res, &timeout, NULL);
4396 if (ret != 0 || res != 0) {
4397 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
4405 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime)
4411 data.dsize = sizeof(*bantime);
4412 data.dptr = (uint8_t *)bantime;
4414 ret = ctdb_control(ctdb, destnode, 0,
4415 CTDB_CONTROL_SET_BAN_STATE, 0, data,
4416 NULL, NULL, &res, &timeout, NULL);
4417 if (ret != 0 || res != 0) {
4418 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4426 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime)
4431 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4433 ret = ctdb_control(ctdb, destnode, 0,
4434 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
4435 tmp_ctx, &outdata, &res, &timeout, NULL);
4436 if (ret != 0 || res != 0) {
4437 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4438 talloc_free(tmp_ctx);
4442 *bantime = (struct ctdb_ban_time *)talloc_steal(mem_ctx, outdata.dptr);
4443 talloc_free(tmp_ctx);
4449 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
4454 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4456 data.dptr = (uint8_t*)db_prio;
4457 data.dsize = sizeof(*db_prio);
4459 ret = ctdb_control(ctdb, destnode, 0,
4460 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
4461 tmp_ctx, NULL, &res, &timeout, NULL);
4462 if (ret != 0 || res != 0) {
4463 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4464 talloc_free(tmp_ctx);
4468 talloc_free(tmp_ctx);
4473 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
4478 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4480 data.dptr = (uint8_t*)&db_id;
4481 data.dsize = sizeof(db_id);
4483 ret = ctdb_control(ctdb, destnode, 0,
4484 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
4485 tmp_ctx, NULL, &res, &timeout, NULL);
4486 if (ret != 0 || res < 0) {
4487 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4488 talloc_free(tmp_ctx);
4496 talloc_free(tmp_ctx);
4501 int ctdb_ctrl_getstathistory(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_statistics_wire **stats)
4507 ret = ctdb_control(ctdb, destnode, 0,
4508 CTDB_CONTROL_GET_STAT_HISTORY, 0, tdb_null,
4509 mem_ctx, &outdata, &res, &timeout, NULL);
4510 if (ret != 0 || res != 0 || outdata.dsize == 0) {
4511 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getstathistory failed ret:%d res:%d\n", ret, res));
4515 *stats = (struct ctdb_statistics_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4516 talloc_free(outdata.dptr);
4521 struct ctdb_ltdb_header *ctdb_header_from_record_handle(struct ctdb_record_handle *h)
4531 struct ctdb_client_control_state *
4532 ctdb_ctrl_updaterecord_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_db_context *ctdb_db, TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA data)
4534 struct ctdb_client_control_state *handle;
4535 struct ctdb_marshall_buffer *m;
4536 struct ctdb_rec_data *rec;
4539 m = talloc_zero(mem_ctx, struct ctdb_marshall_buffer);
4541 DEBUG(DEBUG_ERR, ("Failed to allocate marshall buffer for update record\n"));
4545 m->db_id = ctdb_db->db_id;
4547 rec = ctdb_marshall_record(m, 0, key, header, data);
4549 DEBUG(DEBUG_ERR,("Failed to marshall record for update record\n"));
4553 m = talloc_realloc_size(mem_ctx, m, rec->length + offsetof(struct ctdb_marshall_buffer, data));
4555 DEBUG(DEBUG_CRIT,(__location__ " Failed to expand recdata\n"));
4560 memcpy((uint8_t *)m + offsetof(struct ctdb_marshall_buffer, data), rec, rec->length);
4563 outdata.dptr = (uint8_t *)m;
4564 outdata.dsize = talloc_get_size(m);
4566 handle = ctdb_control_send(ctdb, destnode, 0,
4567 CTDB_CONTROL_UPDATE_RECORD, 0, outdata,
4568 mem_ctx, &timeout, NULL);
4573 int ctdb_ctrl_updaterecord_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4578 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
4579 if ( (ret != 0) || (res != 0) ){
4580 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_update_record_recv failed\n"));
4588 ctdb_ctrl_updaterecord(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_db_context *ctdb_db, TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA data)
4590 struct ctdb_client_control_state *state;
4592 state = ctdb_ctrl_updaterecord_send(ctdb, mem_ctx, timeout, destnode, ctdb_db, key, header, data);
4593 return ctdb_ctrl_updaterecord_recv(ctdb, state);