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 "system/network.h"
26 #include "system/filesys.h"
27 #include "system/locale.h"
29 #include "../include/ctdb_private.h"
30 #include "lib/util/dlinklist.h"
35 allocate a packet for use in client<->daemon communication
37 struct ctdb_req_header *_ctdbd_allocate_pkt(struct ctdb_context *ctdb,
39 enum ctdb_operation operation,
40 size_t length, size_t slength,
44 struct ctdb_req_header *hdr;
46 length = MAX(length, slength);
47 size = (length+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
49 hdr = (struct ctdb_req_header *)talloc_zero_size(mem_ctx, size);
51 DEBUG(DEBUG_ERR,("Unable to allocate packet for operation %u of length %u\n",
52 operation, (unsigned)length));
55 talloc_set_name_const(hdr, type);
57 hdr->operation = operation;
58 hdr->ctdb_magic = CTDB_MAGIC;
59 hdr->ctdb_version = CTDB_VERSION;
60 hdr->srcnode = ctdb->pnn;
62 hdr->generation = ctdb->vnn_map->generation;
69 local version of ctdb_call
71 int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
72 struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx,
73 TDB_DATA *data, bool updatetdb, uint32_t caller)
75 struct ctdb_call_info *c;
76 struct ctdb_registered_call *fn;
77 struct ctdb_context *ctdb = ctdb_db->ctdb;
79 c = talloc(ctdb, struct ctdb_call_info);
80 CTDB_NO_MEMORY(ctdb, c);
83 c->call_data = &call->call_data;
84 c->record_data.dptr = talloc_memdup(c, data->dptr, data->dsize);
85 c->record_data.dsize = data->dsize;
86 CTDB_NO_MEMORY(ctdb, c->record_data.dptr);
92 for (fn=ctdb_db->calls;fn;fn=fn->next) {
93 if (fn->id == call->call_id) break;
96 ctdb_set_error(ctdb, "Unknown call id %u\n", call->call_id);
101 if (fn->fn(c) != 0) {
102 ctdb_set_error(ctdb, "ctdb_call %u failed\n", call->call_id);
107 /* we need to force the record to be written out if this was a remote access */
108 if (header->laccessor != caller) {
111 header->laccessor = caller;
114 /* we need to force the record to be written out if this was a remote access,
115 so that the lacount is updated */
116 if (c->new_data == NULL && header->laccessor != ctdb->pnn) {
117 c->new_data = &c->record_data;
120 if (c->new_data && updatetdb) {
121 /* XXX check that we always have the lock here? */
122 if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
123 ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
130 call->reply_data = *c->reply_data;
132 talloc_steal(call, call->reply_data.dptr);
133 talloc_set_name_const(call->reply_data.dptr, __location__);
135 call->reply_data.dptr = NULL;
136 call->reply_data.dsize = 0;
138 call->status = c->status;
147 queue a packet for sending from client to daemon
149 static int ctdb_client_queue_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
151 return ctdb_queue_send(ctdb->daemon.queue, (uint8_t *)hdr, hdr->length);
156 called when a CTDB_REPLY_CALL packet comes in in the client
158 This packet comes in response to a CTDB_REQ_CALL request packet. It
159 contains any reply data from the call
161 static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
163 struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
164 struct ctdb_client_call_state *state;
166 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_call_state);
168 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
172 if (hdr->reqid != state->reqid) {
173 /* we found a record but it was the wrong one */
174 DEBUG(DEBUG_ERR, ("Dropped client call reply with reqid:%u\n",hdr->reqid));
178 state->call->reply_data.dptr = c->data;
179 state->call->reply_data.dsize = c->datalen;
180 state->call->status = c->status;
182 talloc_steal(state, c);
184 state->state = CTDB_CALL_DONE;
186 if (state->async.fn) {
187 state->async.fn(state);
191 static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
194 this is called in the client, when data comes in from the daemon
196 void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
198 struct ctdb_context *ctdb = talloc_get_type(args, struct ctdb_context);
199 struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
202 /* place the packet as a child of a tmp_ctx. We then use
203 talloc_free() below to free it. If any of the calls want
204 to keep it, then they will steal it somewhere else, and the
205 talloc_free() will be a no-op */
206 tmp_ctx = talloc_new(ctdb);
207 talloc_steal(tmp_ctx, hdr);
210 DEBUG(DEBUG_INFO,("Daemon has exited - shutting down client\n"));
214 if (cnt < sizeof(*hdr)) {
215 DEBUG(DEBUG_CRIT,("Bad packet length %u in client\n", (unsigned)cnt));
218 if (cnt != hdr->length) {
219 ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
220 (unsigned)hdr->length, (unsigned)cnt);
224 if (hdr->ctdb_magic != CTDB_MAGIC) {
225 ctdb_set_error(ctdb, "Non CTDB packet rejected in client\n");
229 if (hdr->ctdb_version != CTDB_VERSION) {
230 ctdb_set_error(ctdb, "Bad CTDB version 0x%x rejected in client\n", hdr->ctdb_version);
234 switch (hdr->operation) {
235 case CTDB_REPLY_CALL:
236 ctdb_client_reply_call(ctdb, hdr);
239 case CTDB_REQ_MESSAGE:
240 ctdb_request_message(ctdb, hdr);
243 case CTDB_REPLY_CONTROL:
244 ctdb_client_reply_control(ctdb, hdr);
248 DEBUG(DEBUG_CRIT,("bogus operation code:%u\n",hdr->operation));
252 talloc_free(tmp_ctx);
256 connect with exponential backoff, thanks Stevens
258 #define CONNECT_MAXSLEEP 64
259 static int ctdb_connect_retry(struct ctdb_context *ctdb)
261 struct sockaddr_un addr;
265 memset(&addr, 0, sizeof(addr));
266 addr.sun_family = AF_UNIX;
267 strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path));
269 for (secs = 1; secs <= CONNECT_MAXSLEEP; secs *= 2) {
270 ret = connect(ctdb->daemon.sd, (struct sockaddr *)&addr,
272 if ((ret == 0) || (errno != EAGAIN)) {
276 if (secs <= (CONNECT_MAXSLEEP / 2)) {
277 DEBUG(DEBUG_ERR,("connect failed: %s, retry in %d second(s)\n",
278 strerror(errno), secs));
287 connect to a unix domain socket
289 int ctdb_socket_connect(struct ctdb_context *ctdb)
291 ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
292 if (ctdb->daemon.sd == -1) {
293 DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
297 set_nonblocking(ctdb->daemon.sd);
298 set_close_on_exec(ctdb->daemon.sd);
300 if (ctdb_connect_retry(ctdb) == -1) {
301 DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
302 close(ctdb->daemon.sd);
303 ctdb->daemon.sd = -1;
307 ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
309 ctdb_client_read_cb, ctdb, "to-ctdbd");
314 struct ctdb_record_handle {
315 struct ctdb_db_context *ctdb_db;
318 struct ctdb_ltdb_header header;
323 make a recv call to the local ctdb daemon - called from client context
325 This is called when the program wants to wait for a ctdb_call to complete and get the
326 results. This call will block unless the call has already completed.
328 int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
334 while (state->state < CTDB_CALL_DONE) {
335 event_loop_once(state->ctdb_db->ctdb->ev);
337 if (state->state != CTDB_CALL_DONE) {
338 DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
343 if (state->call->reply_data.dsize) {
344 call->reply_data.dptr = talloc_memdup(state->ctdb_db,
345 state->call->reply_data.dptr,
346 state->call->reply_data.dsize);
347 call->reply_data.dsize = state->call->reply_data.dsize;
349 call->reply_data.dptr = NULL;
350 call->reply_data.dsize = 0;
352 call->status = state->call->status;
362 destroy a ctdb_call in client
364 static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
366 ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
371 construct an event driven local ctdb_call
373 this is used so that locally processed ctdb_call requests are processed
374 in an event driven manner
376 static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
377 struct ctdb_call *call,
378 struct ctdb_ltdb_header *header,
381 struct ctdb_client_call_state *state;
382 struct ctdb_context *ctdb = ctdb_db->ctdb;
385 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
386 CTDB_NO_MEMORY_NULL(ctdb, state);
387 state->call = talloc_zero(state, struct ctdb_call);
388 CTDB_NO_MEMORY_NULL(ctdb, state->call);
390 talloc_steal(state, data->dptr);
392 state->state = CTDB_CALL_DONE;
393 *(state->call) = *call;
394 state->ctdb_db = ctdb_db;
396 ret = ctdb_call_local(ctdb_db, state->call, header, state, data, true, ctdb->pnn);
398 DEBUG(DEBUG_DEBUG,("ctdb_call_local() failed, ignoring return code %d\n", ret));
405 make a ctdb call to the local daemon - async send. Called from client context.
407 This constructs a ctdb_call request and queues it for processing.
408 This call never blocks.
410 struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
411 struct ctdb_call *call)
413 struct ctdb_client_call_state *state;
414 struct ctdb_context *ctdb = ctdb_db->ctdb;
415 struct ctdb_ltdb_header header;
419 struct ctdb_req_call *c;
421 /* if the domain socket is not yet open, open it */
422 if (ctdb->daemon.sd==-1) {
423 ctdb_socket_connect(ctdb);
426 ret = ctdb_ltdb_lock(ctdb_db, call->key);
428 DEBUG(DEBUG_ERR,(__location__ " Failed to get chainlock\n"));
432 ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
434 if ((call->flags & CTDB_IMMEDIATE_MIGRATION) && (header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
438 if (ret == 0 && header.dmaster == ctdb->pnn) {
439 state = ctdb_client_call_local_send(ctdb_db, call, &header, &data);
440 talloc_free(data.dptr);
441 ctdb_ltdb_unlock(ctdb_db, call->key);
445 ctdb_ltdb_unlock(ctdb_db, call->key);
446 talloc_free(data.dptr);
448 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
450 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state\n"));
453 state->call = talloc_zero(state, struct ctdb_call);
454 if (state->call == NULL) {
455 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state->call\n"));
459 len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
460 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CALL, len, struct ctdb_req_call);
462 DEBUG(DEBUG_ERR, (__location__ " failed to allocate packet\n"));
466 state->reqid = ctdb_reqid_new(ctdb, state);
467 state->ctdb_db = ctdb_db;
468 talloc_set_destructor(state, ctdb_client_call_destructor);
470 c->hdr.reqid = state->reqid;
471 c->flags = call->flags;
472 c->db_id = ctdb_db->db_id;
473 c->callid = call->call_id;
475 c->keylen = call->key.dsize;
476 c->calldatalen = call->call_data.dsize;
477 memcpy(&c->data[0], call->key.dptr, call->key.dsize);
478 memcpy(&c->data[call->key.dsize],
479 call->call_data.dptr, call->call_data.dsize);
480 *(state->call) = *call;
481 state->call->call_data.dptr = &c->data[call->key.dsize];
482 state->call->key.dptr = &c->data[0];
484 state->state = CTDB_CALL_WAIT;
487 ctdb_client_queue_pkt(ctdb, &c->hdr);
494 full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
496 int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
498 struct ctdb_client_call_state *state;
500 state = ctdb_call_send(ctdb_db, call);
501 return ctdb_call_recv(state, call);
506 tell the daemon what messaging srvid we will use, and register the message
507 handler function in the client
509 int ctdb_client_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid,
510 ctdb_msg_fn_t handler,
517 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_REGISTER_SRVID, 0,
518 tdb_null, NULL, NULL, &status, NULL, NULL);
519 if (res != 0 || status != 0) {
520 DEBUG(DEBUG_ERR,("Failed to register srvid %llu\n", (unsigned long long)srvid));
524 /* also need to register the handler with our own ctdb structure */
525 return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
529 tell the daemon we no longer want a srvid
531 int ctdb_client_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid, void *private_data)
536 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_DEREGISTER_SRVID, 0,
537 tdb_null, NULL, NULL, &status, NULL, NULL);
538 if (res != 0 || status != 0) {
539 DEBUG(DEBUG_ERR,("Failed to deregister srvid %llu\n", (unsigned long long)srvid));
543 /* also need to register the handler with our own ctdb structure */
544 ctdb_deregister_message_handler(ctdb, srvid, private_data);
550 send a message - from client context
552 int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t pnn,
553 uint64_t srvid, TDB_DATA data)
555 struct ctdb_req_message *r;
558 len = offsetof(struct ctdb_req_message, data) + data.dsize;
559 r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
560 len, struct ctdb_req_message);
561 CTDB_NO_MEMORY(ctdb, r);
563 r->hdr.destnode = pnn;
565 r->datalen = data.dsize;
566 memcpy(&r->data[0], data.dptr, data.dsize);
568 res = ctdb_client_queue_pkt(ctdb, &r->hdr);
579 cancel a ctdb_fetch_lock operation, releasing the lock
581 static int fetch_lock_destructor(struct ctdb_record_handle *h)
583 ctdb_ltdb_unlock(h->ctdb_db, h->key);
588 force the migration of a record to this node
590 static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
592 struct ctdb_call call;
594 call.call_id = CTDB_NULL_FUNC;
596 call.flags = CTDB_IMMEDIATE_MIGRATION;
597 return ctdb_call(ctdb_db, &call);
601 try to fetch a readonly copy of a record
604 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)
608 struct ctdb_call call;
611 call.call_id = CTDB_FETCH_WITH_HEADER_FUNC;
612 call.call_data.dptr = NULL;
613 call.call_data.dsize = 0;
615 call.flags = CTDB_WANT_READONLY;
616 ret = ctdb_call(ctdb_db, &call);
621 if (call.reply_data.dsize < sizeof(struct ctdb_ltdb_header)) {
625 *hdr = talloc_memdup(mem_ctx, &call.reply_data.dptr[0], sizeof(struct ctdb_ltdb_header));
627 talloc_free(call.reply_data.dptr);
631 data->dsize = call.reply_data.dsize - sizeof(struct ctdb_ltdb_header);
632 data->dptr = talloc_memdup(mem_ctx, &call.reply_data.dptr[sizeof(struct ctdb_ltdb_header)], data->dsize);
633 if (data->dptr == NULL) {
634 talloc_free(call.reply_data.dptr);
643 get a lock on a record, and return the records data. Blocks until it gets the lock
645 struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
646 TDB_DATA key, TDB_DATA *data)
649 struct ctdb_record_handle *h;
652 procedure is as follows:
654 1) get the chain lock.
655 2) check if we are dmaster
656 3) if we are the dmaster then return handle
657 4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
659 5) when we get the reply, goto (1)
662 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
667 h->ctdb_db = ctdb_db;
669 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
670 if (h->key.dptr == NULL) {
676 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize,
677 (const char *)key.dptr));
680 /* step 1 - get the chain lock */
681 ret = ctdb_ltdb_lock(ctdb_db, key);
683 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
688 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
690 talloc_set_destructor(h, fetch_lock_destructor);
692 ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
694 /* when torturing, ensure we test the remote path */
695 if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
697 h->header.dmaster = (uint32_t)-1;
701 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
703 if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
704 ctdb_ltdb_unlock(ctdb_db, key);
705 ret = ctdb_client_force_migration(ctdb_db, key);
707 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
714 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
719 get a readonly lock on a record, and return the records data. Blocks until it gets the lock
721 struct ctdb_record_handle *
722 ctdb_fetch_readonly_lock(
723 struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
724 TDB_DATA key, TDB_DATA *data,
728 struct ctdb_record_handle *h;
729 struct ctdb_ltdb_header *roheader = NULL;
731 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
736 h->ctdb_db = ctdb_db;
738 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
739 if (h->key.dptr == NULL) {
750 talloc_free(roheader);
753 talloc_free(data->dptr);
757 /* Lock the record/chain */
758 ret = ctdb_ltdb_lock(ctdb_db, key);
760 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
765 talloc_set_destructor(h, fetch_lock_destructor);
767 /* Check if record exists yet in the TDB */
768 ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
770 ctdb_ltdb_unlock(ctdb_db, key);
771 ret = ctdb_client_force_migration(ctdb_db, key);
773 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
780 /* if this is a request for read/write and we have delegations
781 we have to revoke all delegations first
784 && (h->header.dmaster == ctdb_db->ctdb->pnn)
785 && (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
786 ctdb_ltdb_unlock(ctdb_db, key);
787 ret = ctdb_client_force_migration(ctdb_db, key);
789 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
796 /* if we are dmaster, just return the handle */
797 if (h->header.dmaster == ctdb_db->ctdb->pnn) {
801 if (read_only != 0) {
802 TDB_DATA rodata = {NULL, 0};
804 if ((h->header.flags & CTDB_REC_RO_HAVE_READONLY)
805 || (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
809 ctdb_ltdb_unlock(ctdb_db, key);
810 ret = ctdb_client_fetch_readonly(ctdb_db, key, h, &roheader, &rodata);
812 DEBUG(DEBUG_ERR,("ctdb_fetch_readonly_lock: failed. force migration and try again\n"));
813 ret = ctdb_client_force_migration(ctdb_db, key);
815 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
823 if (!(roheader->flags&CTDB_REC_RO_HAVE_READONLY)) {
824 ret = ctdb_client_force_migration(ctdb_db, key);
826 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
834 ret = ctdb_ltdb_lock(ctdb_db, key);
836 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
841 ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
843 ctdb_ltdb_unlock(ctdb_db, key);
845 ret = ctdb_client_force_migration(ctdb_db, key);
847 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
858 /* we are not dmaster and this was not a request for a readonly lock
859 * so unlock the record, migrate it and try again
861 ctdb_ltdb_unlock(ctdb_db, key);
862 ret = ctdb_client_force_migration(ctdb_db, key);
864 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
872 store some data to the record that was locked with ctdb_fetch_lock()
874 int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
876 if (h->ctdb_db->persistent) {
877 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
881 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
885 non-locking fetch of a record
887 int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
888 TDB_DATA key, TDB_DATA *data)
890 struct ctdb_call call;
893 call.call_id = CTDB_FETCH_FUNC;
894 call.call_data.dptr = NULL;
895 call.call_data.dsize = 0;
898 ret = ctdb_call(ctdb_db, &call);
901 *data = call.reply_data;
902 talloc_steal(mem_ctx, data->dptr);
911 called when a control completes or timesout to invoke the callback
912 function the user provided
914 static void invoke_control_callback(struct event_context *ev, struct timed_event *te,
915 struct timeval t, void *private_data)
917 struct ctdb_client_control_state *state;
918 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
921 state = talloc_get_type(private_data, struct ctdb_client_control_state);
922 talloc_steal(tmp_ctx, state);
924 ret = ctdb_control_recv(state->ctdb, state, state,
929 DEBUG(DEBUG_DEBUG,("ctdb_control_recv() failed, ignoring return code %d\n", ret));
932 talloc_free(tmp_ctx);
936 called when a CTDB_REPLY_CONTROL packet comes in in the client
938 This packet comes in response to a CTDB_REQ_CONTROL request packet. It
939 contains any reply data from the control
941 static void ctdb_client_reply_control(struct ctdb_context *ctdb,
942 struct ctdb_req_header *hdr)
944 struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
945 struct ctdb_client_control_state *state;
947 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_control_state);
949 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
953 if (hdr->reqid != state->reqid) {
954 /* we found a record but it was the wrong one */
955 DEBUG(DEBUG_ERR, ("Dropped orphaned reply control with reqid:%u\n",hdr->reqid));
959 state->outdata.dptr = c->data;
960 state->outdata.dsize = c->datalen;
961 state->status = c->status;
963 state->errormsg = talloc_strndup(state,
964 (char *)&c->data[c->datalen],
968 /* state->outdata now uses resources from c so we dont want c
969 to just dissappear from under us while state is still alive
971 talloc_steal(state, c);
973 state->state = CTDB_CONTROL_DONE;
975 /* if we had a callback registered for this control, pull the response
976 and call the callback.
978 if (state->async.fn) {
979 event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
985 destroy a ctdb_control in client
987 static int ctdb_client_control_destructor(struct ctdb_client_control_state *state)
989 ctdb_reqid_remove(state->ctdb, state->reqid);
994 /* time out handler for ctdb_control */
995 static void control_timeout_func(struct event_context *ev, struct timed_event *te,
996 struct timeval t, void *private_data)
998 struct ctdb_client_control_state *state = talloc_get_type(private_data, struct ctdb_client_control_state);
1000 DEBUG(DEBUG_ERR,(__location__ " control timed out. reqid:%u opcode:%u "
1001 "dstnode:%u\n", state->reqid, state->c->opcode,
1002 state->c->hdr.destnode));
1004 state->state = CTDB_CONTROL_TIMEOUT;
1006 /* if we had a callback registered for this control, pull the response
1007 and call the callback.
1009 if (state->async.fn) {
1010 event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
1014 /* async version of send control request */
1015 struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
1016 uint32_t destnode, uint64_t srvid,
1017 uint32_t opcode, uint32_t flags, TDB_DATA data,
1018 TALLOC_CTX *mem_ctx,
1019 struct timeval *timeout,
1022 struct ctdb_client_control_state *state;
1024 struct ctdb_req_control *c;
1031 /* if the domain socket is not yet open, open it */
1032 if (ctdb->daemon.sd==-1) {
1033 ctdb_socket_connect(ctdb);
1036 state = talloc_zero(mem_ctx, struct ctdb_client_control_state);
1037 CTDB_NO_MEMORY_NULL(ctdb, state);
1040 state->reqid = ctdb_reqid_new(ctdb, state);
1041 state->state = CTDB_CONTROL_WAIT;
1042 state->errormsg = NULL;
1044 talloc_set_destructor(state, ctdb_client_control_destructor);
1046 len = offsetof(struct ctdb_req_control, data) + data.dsize;
1047 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
1048 len, struct ctdb_req_control);
1050 CTDB_NO_MEMORY_NULL(ctdb, c);
1051 c->hdr.reqid = state->reqid;
1052 c->hdr.destnode = destnode;
1057 c->datalen = data.dsize;
1059 memcpy(&c->data[0], data.dptr, data.dsize);
1063 if (timeout && !timeval_is_zero(timeout)) {
1064 event_add_timed(ctdb->ev, state, *timeout, control_timeout_func, state);
1067 ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
1073 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
1082 /* async version of receive control reply */
1083 int ctdb_control_recv(struct ctdb_context *ctdb,
1084 struct ctdb_client_control_state *state,
1085 TALLOC_CTX *mem_ctx,
1086 TDB_DATA *outdata, int32_t *status, char **errormsg)
1088 TALLOC_CTX *tmp_ctx;
1090 if (status != NULL) {
1093 if (errormsg != NULL) {
1097 if (state == NULL) {
1101 /* prevent double free of state */
1102 tmp_ctx = talloc_new(ctdb);
1103 talloc_steal(tmp_ctx, state);
1105 /* loop one event at a time until we either timeout or the control
1108 while (state->state == CTDB_CONTROL_WAIT) {
1109 event_loop_once(ctdb->ev);
1112 if (state->state != CTDB_CONTROL_DONE) {
1113 DEBUG(DEBUG_ERR,(__location__ " ctdb_control_recv failed\n"));
1114 if (state->async.fn) {
1115 state->async.fn(state);
1117 talloc_free(tmp_ctx);
1121 if (state->errormsg) {
1122 DEBUG(DEBUG_ERR,("ctdb_control error: '%s'\n", state->errormsg));
1124 (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
1126 if (state->async.fn) {
1127 state->async.fn(state);
1129 talloc_free(tmp_ctx);
1134 *outdata = state->outdata;
1135 outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
1139 *status = state->status;
1142 if (state->async.fn) {
1143 state->async.fn(state);
1146 talloc_free(tmp_ctx);
1153 send a ctdb control message
1154 timeout specifies how long we should wait for a reply.
1155 if timeout is NULL we wait indefinitely
1157 int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
1158 uint32_t opcode, uint32_t flags, TDB_DATA data,
1159 TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
1160 struct timeval *timeout,
1163 struct ctdb_client_control_state *state;
1165 state = ctdb_control_send(ctdb, destnode, srvid, opcode,
1166 flags, data, mem_ctx,
1168 return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
1176 a process exists call. Returns 0 if process exists, -1 otherwise
1178 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
1184 data.dptr = (uint8_t*)&pid;
1185 data.dsize = sizeof(pid);
1187 ret = ctdb_control(ctdb, destnode, 0,
1188 CTDB_CONTROL_PROCESS_EXISTS, 0, data,
1189 NULL, NULL, &status, NULL, NULL);
1191 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
1199 get remote statistics
1201 int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
1207 ret = ctdb_control(ctdb, destnode, 0,
1208 CTDB_CONTROL_STATISTICS, 0, tdb_null,
1209 ctdb, &data, &res, NULL, NULL);
1210 if (ret != 0 || res != 0) {
1211 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
1215 if (data.dsize != sizeof(struct ctdb_statistics)) {
1216 DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
1217 (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
1221 *status = *(struct ctdb_statistics *)data.dptr;
1222 talloc_free(data.dptr);
1228 shutdown a remote ctdb node
1230 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1232 struct ctdb_client_control_state *state;
1234 state = ctdb_control_send(ctdb, destnode, 0,
1235 CTDB_CONTROL_SHUTDOWN, 0, tdb_null,
1236 NULL, &timeout, NULL);
1237 if (state == NULL) {
1238 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
1246 get vnn map from a remote node
1248 int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
1253 struct ctdb_vnn_map_wire *map;
1255 ret = ctdb_control(ctdb, destnode, 0,
1256 CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
1257 mem_ctx, &outdata, &res, &timeout, NULL);
1258 if (ret != 0 || res != 0) {
1259 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
1263 map = (struct ctdb_vnn_map_wire *)outdata.dptr;
1264 if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
1265 outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
1266 DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
1270 (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
1271 CTDB_NO_MEMORY(ctdb, *vnnmap);
1272 (*vnnmap)->generation = map->generation;
1273 (*vnnmap)->size = map->size;
1274 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
1276 CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
1277 memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
1278 talloc_free(outdata.dptr);
1285 get the recovery mode of a remote node
1287 struct ctdb_client_control_state *
1288 ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
1290 return ctdb_control_send(ctdb, destnode, 0,
1291 CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
1292 mem_ctx, &timeout, NULL);
1295 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
1300 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1302 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
1307 *recmode = (uint32_t)res;
1313 int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
1315 struct ctdb_client_control_state *state;
1317 state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
1318 return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
1325 set the recovery mode of a remote node
1327 int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
1333 data.dsize = sizeof(uint32_t);
1334 data.dptr = (unsigned char *)&recmode;
1336 ret = ctdb_control(ctdb, destnode, 0,
1337 CTDB_CONTROL_SET_RECMODE, 0, data,
1338 NULL, NULL, &res, &timeout, NULL);
1339 if (ret != 0 || res != 0) {
1340 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
1350 get the recovery master of a remote node
1352 struct ctdb_client_control_state *
1353 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
1354 struct timeval timeout, uint32_t destnode)
1356 return ctdb_control_send(ctdb, destnode, 0,
1357 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
1358 mem_ctx, &timeout, NULL);
1361 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
1366 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1368 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
1373 *recmaster = (uint32_t)res;
1379 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
1381 struct ctdb_client_control_state *state;
1383 state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
1384 return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
1389 set the recovery master of a remote node
1391 int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
1398 data.dsize = sizeof(uint32_t);
1399 data.dptr = (unsigned char *)&recmaster;
1401 ret = ctdb_control(ctdb, destnode, 0,
1402 CTDB_CONTROL_SET_RECMASTER, 0, data,
1403 NULL, NULL, &res, &timeout, NULL);
1404 if (ret != 0 || res != 0) {
1405 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
1414 get a list of databases off a remote node
1416 int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1417 TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
1423 ret = ctdb_control(ctdb, destnode, 0,
1424 CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
1425 mem_ctx, &outdata, &res, &timeout, NULL);
1426 if (ret != 0 || res != 0) {
1427 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
1431 *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1432 talloc_free(outdata.dptr);
1438 get a list of nodes (vnn and flags ) from a remote node
1440 int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
1441 struct timeval timeout, uint32_t destnode,
1442 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1448 ret = ctdb_control(ctdb, destnode, 0,
1449 CTDB_CONTROL_GET_NODEMAP, 0, tdb_null,
1450 mem_ctx, &outdata, &res, &timeout, NULL);
1451 if (ret == 0 && res == -1 && outdata.dsize == 0) {
1452 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
1453 return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
1455 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1456 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
1460 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1461 talloc_free(outdata.dptr);
1467 old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
1469 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb,
1470 struct timeval timeout, uint32_t destnode,
1471 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1475 struct ctdb_node_mapv4 *nodemapv4;
1478 ret = ctdb_control(ctdb, destnode, 0,
1479 CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null,
1480 mem_ctx, &outdata, &res, &timeout, NULL);
1481 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1482 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
1486 nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
1488 len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
1489 (*nodemap) = talloc_zero_size(mem_ctx, len);
1490 CTDB_NO_MEMORY(ctdb, (*nodemap));
1492 (*nodemap)->num = nodemapv4->num;
1493 for (i=0; i<nodemapv4->num; i++) {
1494 (*nodemap)->nodes[i].pnn = nodemapv4->nodes[i].pnn;
1495 (*nodemap)->nodes[i].flags = nodemapv4->nodes[i].flags;
1496 (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
1497 (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
1500 talloc_free(outdata.dptr);
1506 drop the transport, reload the nodes file and restart the transport
1508 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
1509 struct timeval timeout, uint32_t destnode)
1514 ret = ctdb_control(ctdb, destnode, 0,
1515 CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
1516 NULL, NULL, &res, &timeout, NULL);
1517 if (ret != 0 || res != 0) {
1518 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
1527 set vnn map on a node
1529 int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1530 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
1535 struct ctdb_vnn_map_wire *map;
1538 len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
1539 map = talloc_size(mem_ctx, len);
1540 CTDB_NO_MEMORY(ctdb, map);
1542 map->generation = vnnmap->generation;
1543 map->size = vnnmap->size;
1544 memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
1547 data.dptr = (uint8_t *)map;
1549 ret = ctdb_control(ctdb, destnode, 0,
1550 CTDB_CONTROL_SETVNNMAP, 0, data,
1551 NULL, NULL, &res, &timeout, NULL);
1552 if (ret != 0 || res != 0) {
1553 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
1564 async send for pull database
1566 struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
1567 struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
1568 uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
1571 struct ctdb_control_pulldb *pull;
1572 struct ctdb_client_control_state *state;
1574 pull = talloc(mem_ctx, struct ctdb_control_pulldb);
1575 CTDB_NO_MEMORY_NULL(ctdb, pull);
1578 pull->lmaster = lmaster;
1580 indata.dsize = sizeof(struct ctdb_control_pulldb);
1581 indata.dptr = (unsigned char *)pull;
1583 state = ctdb_control_send(ctdb, destnode, 0,
1584 CTDB_CONTROL_PULL_DB, 0, indata,
1585 mem_ctx, &timeout, NULL);
1592 async recv for pull database
1594 int ctdb_ctrl_pulldb_recv(
1595 struct ctdb_context *ctdb,
1596 TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state,
1602 ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
1603 if ( (ret != 0) || (res != 0) ){
1604 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
1612 pull all keys and records for a specific database on a node
1614 int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode,
1615 uint32_t dbid, uint32_t lmaster,
1616 TALLOC_CTX *mem_ctx, struct timeval timeout,
1619 struct ctdb_client_control_state *state;
1621 state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
1624 return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
1629 change dmaster for all keys in the database to the new value
1631 int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1632 TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
1638 indata.dsize = 2*sizeof(uint32_t);
1639 indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
1641 ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
1642 ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
1644 ret = ctdb_control(ctdb, destnode, 0,
1645 CTDB_CONTROL_SET_DMASTER, 0, indata,
1646 NULL, NULL, &res, &timeout, NULL);
1647 if (ret != 0 || res != 0) {
1648 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
1656 ping a node, return number of clients connected
1658 int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
1663 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0,
1664 tdb_null, NULL, NULL, &res, NULL, NULL);
1672 find the real path to a ltdb
1674 int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1681 data.dptr = (uint8_t *)&dbid;
1682 data.dsize = sizeof(dbid);
1684 ret = ctdb_control(ctdb, destnode, 0,
1685 CTDB_CONTROL_GETDBPATH, 0, data,
1686 mem_ctx, &data, &res, &timeout, NULL);
1687 if (ret != 0 || res != 0) {
1691 (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1692 if ((*path) == NULL) {
1696 talloc_free(data.dptr);
1702 find the name of a db
1704 int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1711 data.dptr = (uint8_t *)&dbid;
1712 data.dsize = sizeof(dbid);
1714 ret = ctdb_control(ctdb, destnode, 0,
1715 CTDB_CONTROL_GET_DBNAME, 0, data,
1716 mem_ctx, &data, &res, &timeout, NULL);
1717 if (ret != 0 || res != 0) {
1721 (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1722 if ((*name) == NULL) {
1726 talloc_free(data.dptr);
1732 get the health status of a db
1734 int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
1735 struct timeval timeout,
1737 uint32_t dbid, TALLOC_CTX *mem_ctx,
1738 const char **reason)
1744 data.dptr = (uint8_t *)&dbid;
1745 data.dsize = sizeof(dbid);
1747 ret = ctdb_control(ctdb, destnode, 0,
1748 CTDB_CONTROL_DB_GET_HEALTH, 0, data,
1749 mem_ctx, &data, &res, &timeout, NULL);
1750 if (ret != 0 || res != 0) {
1754 if (data.dsize == 0) {
1759 (*reason) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1760 if ((*reason) == NULL) {
1764 talloc_free(data.dptr);
1772 int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1773 TALLOC_CTX *mem_ctx, const char *name, bool persistent)
1779 data.dptr = discard_const(name);
1780 data.dsize = strlen(name)+1;
1782 ret = ctdb_control(ctdb, destnode, 0,
1783 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1785 mem_ctx, &data, &res, &timeout, NULL);
1787 if (ret != 0 || res != 0) {
1795 get debug level on a node
1797 int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
1803 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
1804 ctdb, &data, &res, NULL, NULL);
1805 if (ret != 0 || res != 0) {
1808 if (data.dsize != sizeof(int32_t)) {
1809 DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
1810 (unsigned)data.dsize));
1813 *level = *(int32_t *)data.dptr;
1814 talloc_free(data.dptr);
1819 set debug level on a node
1821 int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
1827 data.dptr = (uint8_t *)&level;
1828 data.dsize = sizeof(level);
1830 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data,
1831 NULL, NULL, &res, NULL, NULL);
1832 if (ret != 0 || res != 0) {
1840 get a list of connected nodes
1842 uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
1843 struct timeval timeout,
1844 TALLOC_CTX *mem_ctx,
1845 uint32_t *num_nodes)
1847 struct ctdb_node_map *map=NULL;
1853 ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
1858 nodes = talloc_array(mem_ctx, uint32_t, map->num);
1859 if (nodes == NULL) {
1863 for (i=0;i<map->num;i++) {
1864 if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
1865 nodes[*num_nodes] = map->nodes[i].pnn;
1877 int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
1882 ret = ctdb_control(ctdb, destnode, 0,
1883 CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null,
1884 NULL, NULL, &res, NULL, NULL);
1885 if (ret != 0 || res != 0) {
1886 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
1893 attach to a specific database - client call
1895 struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
1896 struct timeval timeout,
1901 struct ctdb_db_context *ctdb_db;
1906 ctdb_db = ctdb_db_handle(ctdb, name);
1911 ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
1912 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
1914 ctdb_db->ctdb = ctdb;
1915 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
1916 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
1918 data.dptr = discard_const(name);
1919 data.dsize = strlen(name)+1;
1921 /* tell ctdb daemon to attach */
1922 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags,
1923 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1924 0, data, ctdb_db, &data, &res, NULL, NULL);
1925 if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
1926 DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
1927 talloc_free(ctdb_db);
1931 ctdb_db->db_id = *(uint32_t *)data.dptr;
1932 talloc_free(data.dptr);
1934 ret = ctdb_ctrl_getdbpath(ctdb, timeout, CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
1936 DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
1937 talloc_free(ctdb_db);
1941 tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
1942 if (ctdb->valgrinding) {
1943 tdb_flags |= TDB_NOMMAP;
1945 tdb_flags |= TDB_DISALLOW_NESTING;
1947 ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
1948 if (ctdb_db->ltdb == NULL) {
1949 ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
1950 talloc_free(ctdb_db);
1954 ctdb_db->persistent = persistent;
1956 DLIST_ADD(ctdb->db_list, ctdb_db);
1958 /* add well known functions */
1959 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
1960 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
1961 ctdb_set_call(ctdb_db, ctdb_fetch_with_header_func, CTDB_FETCH_WITH_HEADER_FUNC);
1968 setup a call for a database
1970 int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
1972 struct ctdb_registered_call *call;
1977 struct ctdb_control_set_call c;
1980 /* this is no longer valid with the separate daemon architecture */
1981 c.db_id = ctdb_db->db_id;
1985 data.dptr = (uint8_t *)&c;
1986 data.dsize = sizeof(c);
1988 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_SET_CALL, 0,
1989 data, NULL, NULL, &status, NULL, NULL);
1990 if (ret != 0 || status != 0) {
1991 DEBUG(DEBUG_ERR,("ctdb_set_call failed for call %u\n", id));
1996 /* also register locally */
1997 call = talloc(ctdb_db, struct ctdb_registered_call);
2001 DLIST_ADD(ctdb_db->calls, call);
2006 struct traverse_state {
2009 ctdb_traverse_func fn;
2011 bool listemptyrecords;
2015 called on each key during a ctdb_traverse
2017 static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p)
2019 struct traverse_state *state = (struct traverse_state *)p;
2020 struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
2023 if (data.dsize < sizeof(uint32_t) ||
2024 d->length != data.dsize) {
2025 DEBUG(DEBUG_ERR,("Bad data size %u in traverse_handler\n", (unsigned)data.dsize));
2030 key.dsize = d->keylen;
2031 key.dptr = &d->data[0];
2032 data.dsize = d->datalen;
2033 data.dptr = &d->data[d->keylen];
2035 if (key.dsize == 0 && data.dsize == 0) {
2036 /* end of traverse */
2041 if (!state->listemptyrecords &&
2042 data.dsize == sizeof(struct ctdb_ltdb_header))
2044 /* empty records are deleted records in ctdb */
2048 if (state->fn(ctdb, key, data, state->private_data) != 0) {
2056 * start a cluster wide traverse, calling the supplied fn on each record
2057 * return the number of records traversed, or -1 on error
2059 * Extendet variant with a flag to signal whether empty records should
2062 static int ctdb_traverse_ext(struct ctdb_db_context *ctdb_db,
2063 ctdb_traverse_func fn,
2064 bool withemptyrecords,
2068 struct ctdb_traverse_start_ext t;
2071 uint64_t srvid = (getpid() | 0xFLL<<60);
2072 struct traverse_state state;
2076 state.private_data = private_data;
2078 state.listemptyrecords = withemptyrecords;
2080 ret = ctdb_client_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
2082 DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
2086 t.db_id = ctdb_db->db_id;
2089 t.withemptyrecords = withemptyrecords;
2091 data.dptr = (uint8_t *)&t;
2092 data.dsize = sizeof(t);
2094 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START_EXT, 0,
2095 data, NULL, NULL, &status, NULL, NULL);
2096 if (ret != 0 || status != 0) {
2097 DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
2098 ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2102 while (!state.done) {
2103 event_loop_once(ctdb_db->ctdb->ev);
2106 ret = ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2108 DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
2116 * start a cluster wide traverse, calling the supplied fn on each record
2117 * return the number of records traversed, or -1 on error
2119 * Standard version which does not list the empty records:
2120 * These are considered deleted.
2122 int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
2124 return ctdb_traverse_ext(ctdb_db, fn, false, private_data);
2127 #define ISASCII(x) (isprint(x) && !strchr("\"\\", (x)))
2129 called on each key during a catdb
2131 int ctdb_dumpdb_record(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p)
2134 struct ctdb_dump_db_context *c = (struct ctdb_dump_db_context *)p;
2136 struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
2138 fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
2139 for (i=0;i<key.dsize;i++) {
2140 if (ISASCII(key.dptr[i])) {
2141 fprintf(f, "%c", key.dptr[i]);
2143 fprintf(f, "\\%02X", key.dptr[i]);
2148 fprintf(f, "dmaster: %u\n", h->dmaster);
2149 fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
2151 if (c->printlmaster && ctdb->vnn_map != NULL) {
2152 fprintf(f, "lmaster: %u\n", ctdb_lmaster(ctdb, &key));
2156 fprintf(f, "hash: 0x%08x\n", ctdb_hash(&key));
2159 if (c->printrecordflags) {
2160 fprintf(f, "flags: 0x%08x", h->flags);
2161 if (h->flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA) printf(" MIGRATED_WITH_DATA");
2162 if (h->flags & CTDB_REC_FLAG_VACUUM_MIGRATED) printf(" VACUUM_MIGRATED");
2163 if (h->flags & CTDB_REC_FLAG_AUTOMATIC) printf(" AUTOMATIC");
2164 if (h->flags & CTDB_REC_RO_HAVE_DELEGATIONS) printf(" RO_HAVE_DELEGATIONS");
2165 if (h->flags & CTDB_REC_RO_HAVE_READONLY) printf(" RO_HAVE_READONLY");
2166 if (h->flags & CTDB_REC_RO_REVOKING_READONLY) printf(" RO_REVOKING_READONLY");
2167 if (h->flags & CTDB_REC_RO_REVOKE_COMPLETE) printf(" RO_REVOKE_COMPLETE");
2171 if (c->printdatasize) {
2172 fprintf(f, "data size: %u\n", (unsigned)data.dsize);
2174 fprintf(f, "data(%u) = \"", (unsigned)(data.dsize - sizeof(*h)));
2175 for (i=sizeof(*h);i<data.dsize;i++) {
2176 if (ISASCII(data.dptr[i])) {
2177 fprintf(f, "%c", data.dptr[i]);
2179 fprintf(f, "\\%02X", data.dptr[i]);
2191 convenience function to list all keys to stdout
2193 int ctdb_dump_db(struct ctdb_db_context *ctdb_db,
2194 struct ctdb_dump_db_context *ctx)
2196 return ctdb_traverse_ext(ctdb_db, ctdb_dumpdb_record,
2197 ctx->printemptyrecords, ctx);
2201 get the pid of a ctdb daemon
2203 int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
2208 ret = ctdb_control(ctdb, destnode, 0,
2209 CTDB_CONTROL_GET_PID, 0, tdb_null,
2210 NULL, NULL, &res, &timeout, NULL);
2212 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
2223 async freeze send control
2225 struct ctdb_client_control_state *
2226 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
2228 return ctdb_control_send(ctdb, destnode, priority,
2229 CTDB_CONTROL_FREEZE, 0, tdb_null,
2230 mem_ctx, &timeout, NULL);
2234 async freeze recv control
2236 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
2241 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
2242 if ( (ret != 0) || (res != 0) ){
2243 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
2251 freeze databases of a certain priority
2253 int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2255 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2256 struct ctdb_client_control_state *state;
2259 state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
2260 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
2261 talloc_free(tmp_ctx);
2266 /* Freeze all databases */
2267 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2271 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
2272 if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
2280 thaw databases of a certain priority
2282 int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2287 ret = ctdb_control(ctdb, destnode, priority,
2288 CTDB_CONTROL_THAW, 0, tdb_null,
2289 NULL, NULL, &res, &timeout, NULL);
2290 if (ret != 0 || res != 0) {
2291 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
2298 /* thaw all databases */
2299 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2301 return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
2305 get pnn of a node, or -1
2307 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2312 ret = ctdb_control(ctdb, destnode, 0,
2313 CTDB_CONTROL_GET_PNN, 0, tdb_null,
2314 NULL, NULL, &res, &timeout, NULL);
2316 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
2324 get the monitoring mode of a remote node
2326 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
2331 ret = ctdb_control(ctdb, destnode, 0,
2332 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
2333 NULL, NULL, &res, &timeout, NULL);
2335 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
2346 set the monitoring mode of a remote node to active
2348 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2353 ret = ctdb_control(ctdb, destnode, 0,
2354 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
2355 NULL, NULL,NULL, &timeout, NULL);
2357 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
2367 set the monitoring mode of a remote node to disable
2369 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2374 ret = ctdb_control(ctdb, destnode, 0,
2375 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
2376 NULL, NULL, NULL, &timeout, NULL);
2378 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
2390 sent to a node to make it take over an ip address
2392 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
2393 uint32_t destnode, struct ctdb_public_ip *ip)
2396 struct ctdb_public_ipv4 ipv4;
2400 if (ip->addr.sa.sa_family == AF_INET) {
2402 ipv4.sin = ip->addr.ip;
2404 data.dsize = sizeof(ipv4);
2405 data.dptr = (uint8_t *)&ipv4;
2407 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
2408 NULL, &res, &timeout, NULL);
2410 data.dsize = sizeof(*ip);
2411 data.dptr = (uint8_t *)ip;
2413 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
2414 NULL, &res, &timeout, NULL);
2417 if (ret != 0 || res != 0) {
2418 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
2427 sent to a node to make it release an ip address
2429 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
2430 uint32_t destnode, struct ctdb_public_ip *ip)
2433 struct ctdb_public_ipv4 ipv4;
2437 if (ip->addr.sa.sa_family == AF_INET) {
2439 ipv4.sin = ip->addr.ip;
2441 data.dsize = sizeof(ipv4);
2442 data.dptr = (uint8_t *)&ipv4;
2444 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
2445 NULL, &res, &timeout, NULL);
2447 data.dsize = sizeof(*ip);
2448 data.dptr = (uint8_t *)ip;
2450 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
2451 NULL, &res, &timeout, NULL);
2454 if (ret != 0 || res != 0) {
2455 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
2466 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
2467 struct timeval timeout,
2469 const char *name, uint32_t *value)
2471 struct ctdb_control_get_tunable *t;
2472 TDB_DATA data, outdata;
2476 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
2477 data.dptr = talloc_size(ctdb, data.dsize);
2478 CTDB_NO_MEMORY(ctdb, data.dptr);
2480 t = (struct ctdb_control_get_tunable *)data.dptr;
2481 t->length = strlen(name)+1;
2482 memcpy(t->name, name, t->length);
2484 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
2485 &outdata, &res, &timeout, NULL);
2486 talloc_free(data.dptr);
2487 if (ret != 0 || res != 0) {
2488 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
2492 if (outdata.dsize != sizeof(uint32_t)) {
2493 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
2494 talloc_free(outdata.dptr);
2498 *value = *(uint32_t *)outdata.dptr;
2499 talloc_free(outdata.dptr);
2507 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
2508 struct timeval timeout,
2510 const char *name, uint32_t value)
2512 struct ctdb_control_set_tunable *t;
2517 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
2518 data.dptr = talloc_size(ctdb, data.dsize);
2519 CTDB_NO_MEMORY(ctdb, data.dptr);
2521 t = (struct ctdb_control_set_tunable *)data.dptr;
2522 t->length = strlen(name)+1;
2523 memcpy(t->name, name, t->length);
2526 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
2527 NULL, &res, &timeout, NULL);
2528 talloc_free(data.dptr);
2529 if (ret != 0 || res != 0) {
2530 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
2540 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
2541 struct timeval timeout,
2543 TALLOC_CTX *mem_ctx,
2544 const char ***list, uint32_t *count)
2549 struct ctdb_control_list_tunable *t;
2552 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
2553 mem_ctx, &outdata, &res, &timeout, NULL);
2554 if (ret != 0 || res != 0) {
2555 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
2559 t = (struct ctdb_control_list_tunable *)outdata.dptr;
2560 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
2561 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
2562 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
2563 talloc_free(outdata.dptr);
2567 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
2568 CTDB_NO_MEMORY(ctdb, p);
2570 talloc_free(outdata.dptr);
2575 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
2576 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
2577 CTDB_NO_MEMORY(ctdb, *list);
2578 (*list)[*count] = talloc_strdup(*list, s);
2579 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
2589 int ctdb_ctrl_get_public_ips_flags(struct ctdb_context *ctdb,
2590 struct timeval timeout, uint32_t destnode,
2591 TALLOC_CTX *mem_ctx,
2593 struct ctdb_all_public_ips **ips)
2599 ret = ctdb_control(ctdb, destnode, 0,
2600 CTDB_CONTROL_GET_PUBLIC_IPS, flags, tdb_null,
2601 mem_ctx, &outdata, &res, &timeout, NULL);
2602 if (ret == 0 && res == -1) {
2603 DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
2604 return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
2606 if (ret != 0 || res != 0) {
2607 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
2611 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
2612 talloc_free(outdata.dptr);
2617 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
2618 struct timeval timeout, uint32_t destnode,
2619 TALLOC_CTX *mem_ctx,
2620 struct ctdb_all_public_ips **ips)
2622 return ctdb_ctrl_get_public_ips_flags(ctdb, timeout,
2627 int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
2628 struct timeval timeout, uint32_t destnode,
2629 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
2634 struct ctdb_all_public_ipsv4 *ipsv4;
2636 ret = ctdb_control(ctdb, destnode, 0,
2637 CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null,
2638 mem_ctx, &outdata, &res, &timeout, NULL);
2639 if (ret != 0 || res != 0) {
2640 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
2644 ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
2645 len = offsetof(struct ctdb_all_public_ips, ips) +
2646 ipsv4->num*sizeof(struct ctdb_public_ip);
2647 *ips = talloc_zero_size(mem_ctx, len);
2648 CTDB_NO_MEMORY(ctdb, *ips);
2649 (*ips)->num = ipsv4->num;
2650 for (i=0; i<ipsv4->num; i++) {
2651 (*ips)->ips[i].pnn = ipsv4->ips[i].pnn;
2652 (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
2655 talloc_free(outdata.dptr);
2660 int ctdb_ctrl_get_public_ip_info(struct ctdb_context *ctdb,
2661 struct timeval timeout, uint32_t destnode,
2662 TALLOC_CTX *mem_ctx,
2663 const ctdb_sock_addr *addr,
2664 struct ctdb_control_public_ip_info **_info)
2670 struct ctdb_control_public_ip_info *info;
2674 indata.dptr = discard_const_p(uint8_t, addr);
2675 indata.dsize = sizeof(*addr);
2677 ret = ctdb_control(ctdb, destnode, 0,
2678 CTDB_CONTROL_GET_PUBLIC_IP_INFO, 0, indata,
2679 mem_ctx, &outdata, &res, &timeout, NULL);
2680 if (ret != 0 || res != 0) {
2681 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2682 "failed ret:%d res:%d\n",
2687 len = offsetof(struct ctdb_control_public_ip_info, ifaces);
2688 if (len > outdata.dsize) {
2689 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2690 "returned invalid data with size %u > %u\n",
2691 (unsigned int)outdata.dsize,
2692 (unsigned int)len));
2693 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2697 info = (struct ctdb_control_public_ip_info *)outdata.dptr;
2698 len += info->num*sizeof(struct ctdb_control_iface_info);
2700 if (len > outdata.dsize) {
2701 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2702 "returned invalid data with size %u > %u\n",
2703 (unsigned int)outdata.dsize,
2704 (unsigned int)len));
2705 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2709 /* make sure we null terminate the returned strings */
2710 for (i=0; i < info->num; i++) {
2711 info->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2714 *_info = (struct ctdb_control_public_ip_info *)talloc_memdup(mem_ctx,
2717 talloc_free(outdata.dptr);
2718 if (*_info == NULL) {
2719 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2720 "talloc_memdup size %u failed\n",
2721 (unsigned int)outdata.dsize));
2728 int ctdb_ctrl_get_ifaces(struct ctdb_context *ctdb,
2729 struct timeval timeout, uint32_t destnode,
2730 TALLOC_CTX *mem_ctx,
2731 struct ctdb_control_get_ifaces **_ifaces)
2736 struct ctdb_control_get_ifaces *ifaces;
2740 ret = ctdb_control(ctdb, destnode, 0,
2741 CTDB_CONTROL_GET_IFACES, 0, tdb_null,
2742 mem_ctx, &outdata, &res, &timeout, NULL);
2743 if (ret != 0 || res != 0) {
2744 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2745 "failed ret:%d res:%d\n",
2750 len = offsetof(struct ctdb_control_get_ifaces, ifaces);
2751 if (len > outdata.dsize) {
2752 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2753 "returned invalid data with size %u > %u\n",
2754 (unsigned int)outdata.dsize,
2755 (unsigned int)len));
2756 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2760 ifaces = (struct ctdb_control_get_ifaces *)outdata.dptr;
2761 len += ifaces->num*sizeof(struct ctdb_control_iface_info);
2763 if (len > outdata.dsize) {
2764 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2765 "returned invalid data with size %u > %u\n",
2766 (unsigned int)outdata.dsize,
2767 (unsigned int)len));
2768 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2772 /* make sure we null terminate the returned strings */
2773 for (i=0; i < ifaces->num; i++) {
2774 ifaces->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2777 *_ifaces = (struct ctdb_control_get_ifaces *)talloc_memdup(mem_ctx,
2780 talloc_free(outdata.dptr);
2781 if (*_ifaces == NULL) {
2782 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2783 "talloc_memdup size %u failed\n",
2784 (unsigned int)outdata.dsize));
2791 int ctdb_ctrl_set_iface_link(struct ctdb_context *ctdb,
2792 struct timeval timeout, uint32_t destnode,
2793 TALLOC_CTX *mem_ctx,
2794 const struct ctdb_control_iface_info *info)
2800 indata.dptr = discard_const_p(uint8_t, info);
2801 indata.dsize = sizeof(*info);
2803 ret = ctdb_control(ctdb, destnode, 0,
2804 CTDB_CONTROL_SET_IFACE_LINK_STATE, 0, indata,
2805 mem_ctx, NULL, &res, &timeout, NULL);
2806 if (ret != 0 || res != 0) {
2807 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set iface link "
2808 "failed ret:%d res:%d\n",
2817 set/clear the permanent disabled bit on a remote node
2819 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
2820 uint32_t set, uint32_t clear)
2824 struct ctdb_node_map *nodemap=NULL;
2825 struct ctdb_node_flag_change c;
2826 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2831 /* find the recovery master */
2832 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
2834 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
2835 talloc_free(tmp_ctx);
2840 /* read the node flags from the recmaster */
2841 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
2843 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
2844 talloc_free(tmp_ctx);
2847 if (destnode >= nodemap->num) {
2848 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
2849 talloc_free(tmp_ctx);
2854 c.old_flags = nodemap->nodes[destnode].flags;
2855 c.new_flags = c.old_flags;
2857 c.new_flags &= ~clear;
2859 data.dsize = sizeof(c);
2860 data.dptr = (unsigned char *)&c;
2862 /* send the flags update to all connected nodes */
2863 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
2865 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
2867 timeout, false, data,
2870 DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
2872 talloc_free(tmp_ctx);
2876 talloc_free(tmp_ctx);
2884 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
2885 struct timeval timeout,
2887 struct ctdb_tunable *tunables)
2893 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
2894 &outdata, &res, &timeout, NULL);
2895 if (ret != 0 || res != 0) {
2896 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
2900 if (outdata.dsize != sizeof(*tunables)) {
2901 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
2902 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
2906 *tunables = *(struct ctdb_tunable *)outdata.dptr;
2907 talloc_free(outdata.dptr);
2912 add a public address to a node
2914 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
2915 struct timeval timeout,
2917 struct ctdb_control_ip_iface *pub)
2923 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2924 data.dptr = (unsigned char *)pub;
2926 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
2927 NULL, &res, &timeout, NULL);
2928 if (ret != 0 || res != 0) {
2929 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
2937 delete a public address from a node
2939 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
2940 struct timeval timeout,
2942 struct ctdb_control_ip_iface *pub)
2948 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2949 data.dptr = (unsigned char *)pub;
2951 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
2952 NULL, &res, &timeout, NULL);
2953 if (ret != 0 || res != 0) {
2954 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
2962 kill a tcp connection
2964 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
2965 struct timeval timeout,
2967 struct ctdb_control_killtcp *killtcp)
2973 data.dsize = sizeof(struct ctdb_control_killtcp);
2974 data.dptr = (unsigned char *)killtcp;
2976 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
2977 NULL, &res, &timeout, NULL);
2978 if (ret != 0 || res != 0) {
2979 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
2989 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
2990 struct timeval timeout,
2992 ctdb_sock_addr *addr,
2998 struct ctdb_control_gratious_arp *gratious_arp;
2999 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3002 len = strlen(ifname)+1;
3003 gratious_arp = talloc_size(tmp_ctx,
3004 offsetof(struct ctdb_control_gratious_arp, iface) + len);
3005 CTDB_NO_MEMORY(ctdb, gratious_arp);
3007 gratious_arp->addr = *addr;
3008 gratious_arp->len = len;
3009 memcpy(&gratious_arp->iface[0], ifname, len);
3012 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
3013 data.dptr = (unsigned char *)gratious_arp;
3015 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
3016 NULL, &res, &timeout, NULL);
3017 if (ret != 0 || res != 0) {
3018 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
3019 talloc_free(tmp_ctx);
3023 talloc_free(tmp_ctx);
3028 get a list of all tcp tickles that a node knows about for a particular vnn
3030 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
3031 struct timeval timeout, uint32_t destnode,
3032 TALLOC_CTX *mem_ctx,
3033 ctdb_sock_addr *addr,
3034 struct ctdb_control_tcp_tickle_list **list)
3037 TDB_DATA data, outdata;
3040 data.dptr = (uint8_t*)addr;
3041 data.dsize = sizeof(ctdb_sock_addr);
3043 ret = ctdb_control(ctdb, destnode, 0,
3044 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
3045 mem_ctx, &outdata, &status, NULL, NULL);
3046 if (ret != 0 || status != 0) {
3047 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
3051 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
3057 register a server id
3059 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
3060 struct timeval timeout,
3061 struct ctdb_server_id *id)
3067 data.dsize = sizeof(struct ctdb_server_id);
3068 data.dptr = (unsigned char *)id;
3070 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3071 CTDB_CONTROL_REGISTER_SERVER_ID,
3073 NULL, &res, &timeout, NULL);
3074 if (ret != 0 || res != 0) {
3075 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
3083 unregister a server id
3085 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
3086 struct timeval timeout,
3087 struct ctdb_server_id *id)
3093 data.dsize = sizeof(struct ctdb_server_id);
3094 data.dptr = (unsigned char *)id;
3096 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3097 CTDB_CONTROL_UNREGISTER_SERVER_ID,
3099 NULL, &res, &timeout, NULL);
3100 if (ret != 0 || res != 0) {
3101 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
3110 check if a server id exists
3112 if a server id does exist, return *status == 1, otherwise *status == 0
3114 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
3115 struct timeval timeout,
3117 struct ctdb_server_id *id,
3124 data.dsize = sizeof(struct ctdb_server_id);
3125 data.dptr = (unsigned char *)id;
3127 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
3129 NULL, &res, &timeout, NULL);
3131 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
3145 get the list of server ids that are registered on a node
3147 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
3148 TALLOC_CTX *mem_ctx,
3149 struct timeval timeout, uint32_t destnode,
3150 struct ctdb_server_id_list **svid_list)
3156 ret = ctdb_control(ctdb, destnode, 0,
3157 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
3158 mem_ctx, &outdata, &res, &timeout, NULL);
3159 if (ret != 0 || res != 0) {
3160 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
3164 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
3170 initialise the ctdb daemon for client applications
3172 NOTE: In current code the daemon does not fork. This is for testing purposes only
3173 and to simplify the code.
3175 struct ctdb_context *ctdb_init(struct event_context *ev)
3178 struct ctdb_context *ctdb;
3180 ctdb = talloc_zero(ev, struct ctdb_context);
3182 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
3186 ctdb->idr = idr_init(ctdb);
3187 /* Wrap early to exercise code. */
3188 ctdb->lastid = INT_MAX-200;
3189 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
3191 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
3193 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
3198 ctdb->statistics.statistics_start_time = timeval_current();
3207 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
3209 ctdb->flags |= flags;
3213 setup the local socket name
3215 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
3217 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
3218 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
3223 const char *ctdb_get_socketname(struct ctdb_context *ctdb)
3225 return ctdb->daemon.name;
3229 return the pnn of this node
3231 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
3238 get the uptime of a remote node
3240 struct ctdb_client_control_state *
3241 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3243 return ctdb_control_send(ctdb, destnode, 0,
3244 CTDB_CONTROL_UPTIME, 0, tdb_null,
3245 mem_ctx, &timeout, NULL);
3248 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
3254 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3255 if (ret != 0 || res != 0) {
3256 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
3260 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
3265 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
3267 struct ctdb_client_control_state *state;
3269 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
3270 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
3274 send a control to execute the "recovered" event script on a node
3276 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3281 ret = ctdb_control(ctdb, destnode, 0,
3282 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
3283 NULL, NULL, &status, &timeout, NULL);
3284 if (ret != 0 || status != 0) {
3285 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
3293 callback for the async helpers used when sending the same control
3294 to multiple nodes in parallell.
3296 static void async_callback(struct ctdb_client_control_state *state)
3298 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
3299 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
3303 uint32_t destnode = state->c->hdr.destnode;
3305 /* one more node has responded with recmode data */
3308 /* if we failed to push the db, then return an error and let
3309 the main loop try again.
3311 if (state->state != CTDB_CONTROL_DONE) {
3312 if ( !data->dont_log_errors) {
3313 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
3316 if (data->fail_callback) {
3317 data->fail_callback(ctdb, destnode, res, outdata,
3318 data->callback_data);
3323 state->async.fn = NULL;
3325 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
3326 if ((ret != 0) || (res != 0)) {
3327 if ( !data->dont_log_errors) {
3328 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
3331 if (data->fail_callback) {
3332 data->fail_callback(ctdb, destnode, res, outdata,
3333 data->callback_data);
3336 if ((ret == 0) && (data->callback != NULL)) {
3337 data->callback(ctdb, destnode, res, outdata,
3338 data->callback_data);
3343 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
3345 /* set up the callback functions */
3346 state->async.fn = async_callback;
3347 state->async.private_data = data;
3349 /* one more control to wait for to complete */
3354 /* wait for up to the maximum number of seconds allowed
3355 or until all nodes we expect a response from has replied
3357 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
3359 while (data->count > 0) {
3360 event_loop_once(ctdb->ev);
3362 if (data->fail_count != 0) {
3363 if (!data->dont_log_errors) {
3364 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
3374 perform a simple control on the listed nodes
3375 The control cannot return data
3377 int ctdb_client_async_control(struct ctdb_context *ctdb,
3378 enum ctdb_controls opcode,
3381 struct timeval timeout,
3382 bool dont_log_errors,
3384 client_async_callback client_callback,
3385 client_async_callback fail_callback,
3386 void *callback_data)
3388 struct client_async_data *async_data;
3389 struct ctdb_client_control_state *state;
3392 async_data = talloc_zero(ctdb, struct client_async_data);
3393 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
3394 async_data->dont_log_errors = dont_log_errors;
3395 async_data->callback = client_callback;
3396 async_data->fail_callback = fail_callback;
3397 async_data->callback_data = callback_data;
3398 async_data->opcode = opcode;
3400 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
3402 /* loop over all nodes and send an async control to each of them */
3403 for (j=0; j<num_nodes; j++) {
3404 uint32_t pnn = nodes[j];
3406 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
3407 0, data, async_data, &timeout, NULL);
3408 if (state == NULL) {
3409 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
3410 talloc_free(async_data);
3414 ctdb_client_async_add(async_data, state);
3417 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
3418 talloc_free(async_data);
3422 talloc_free(async_data);
3426 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
3427 struct ctdb_vnn_map *vnn_map,
3428 TALLOC_CTX *mem_ctx,
3431 int i, j, num_nodes;
3434 for (i=num_nodes=0;i<vnn_map->size;i++) {
3435 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3441 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3442 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3444 for (i=j=0;i<vnn_map->size;i++) {
3445 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3448 nodes[j++] = vnn_map->map[i];
3454 /* Get list of nodes not including those with flags specified by mask.
3455 * If exclude_pnn is not -1 then exclude that pnn from the list.
3457 uint32_t *list_of_nodes(struct ctdb_context *ctdb,
3458 struct ctdb_node_map *node_map,
3459 TALLOC_CTX *mem_ctx,
3463 int i, j, num_nodes;
3466 for (i=num_nodes=0;i<node_map->num;i++) {
3467 if (node_map->nodes[i].flags & mask) {
3470 if (node_map->nodes[i].pnn == exclude_pnn) {
3476 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3477 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3479 for (i=j=0;i<node_map->num;i++) {
3480 if (node_map->nodes[i].flags & mask) {
3483 if (node_map->nodes[i].pnn == exclude_pnn) {
3486 nodes[j++] = node_map->nodes[i].pnn;
3492 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
3493 struct ctdb_node_map *node_map,
3494 TALLOC_CTX *mem_ctx,
3497 int i, j, num_nodes;
3500 for (i=num_nodes=0;i<node_map->num;i++) {
3501 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3504 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3510 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3511 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3513 for (i=j=0;i<node_map->num;i++) {
3514 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3517 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3520 nodes[j++] = node_map->nodes[i].pnn;
3526 uint32_t *list_of_active_nodes_except_pnn(struct ctdb_context *ctdb,
3527 struct ctdb_node_map *node_map,
3528 TALLOC_CTX *mem_ctx,
3531 int i, j, num_nodes;
3534 for (i=num_nodes=0;i<node_map->num;i++) {
3535 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3538 if (node_map->nodes[i].pnn == pnn) {
3544 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3545 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3547 for (i=j=0;i<node_map->num;i++) {
3548 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
3551 if (node_map->nodes[i].pnn == pnn) {
3554 nodes[j++] = node_map->nodes[i].pnn;
3560 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
3561 struct ctdb_node_map *node_map,
3562 TALLOC_CTX *mem_ctx,
3565 int i, j, num_nodes;
3568 for (i=num_nodes=0;i<node_map->num;i++) {
3569 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3572 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3578 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3579 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3581 for (i=j=0;i<node_map->num;i++) {
3582 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
3585 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
3588 nodes[j++] = node_map->nodes[i].pnn;
3595 this is used to test if a pnn lock exists and if it exists will return
3596 the number of connections that pnn has reported or -1 if that recovery
3597 daemon is not running.
3600 ctdb_read_pnn_lock(int fd, int32_t pnn)
3605 lock.l_type = F_WRLCK;
3606 lock.l_whence = SEEK_SET;
3611 if (fcntl(fd, F_GETLK, &lock) != 0) {
3612 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3616 if (lock.l_type == F_UNLCK) {
3620 if (pread(fd, &c, 1, pnn) == -1) {
3621 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3629 get capabilities of a remote node
3631 struct ctdb_client_control_state *
3632 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3634 return ctdb_control_send(ctdb, destnode, 0,
3635 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3636 mem_ctx, &timeout, NULL);
3639 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3645 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3646 if ( (ret != 0) || (res != 0) ) {
3647 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3652 *capabilities = *((uint32_t *)outdata.dptr);
3658 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3660 struct ctdb_client_control_state *state;
3661 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3664 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3665 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3666 talloc_free(tmp_ctx);
3671 * check whether a transaction is active on a given db on a given node
3673 int32_t ctdb_ctrl_transaction_active(struct ctdb_context *ctdb,
3681 indata.dptr = (uint8_t *)&db_id;
3682 indata.dsize = sizeof(db_id);
3684 ret = ctdb_control(ctdb, destnode, 0,
3685 CTDB_CONTROL_TRANS2_ACTIVE,
3686 0, indata, NULL, NULL, &status,
3690 DEBUG(DEBUG_ERR, (__location__ " ctdb control for transaction_active failed\n"));
3698 struct ctdb_transaction_handle {
3699 struct ctdb_db_context *ctdb_db;
3702 * we store the reads and writes done under a transaction:
3703 * - one list stores both reads and writes (m_all),
3704 * - the other just writes (m_write)
3706 struct ctdb_marshall_buffer *m_all;
3707 struct ctdb_marshall_buffer *m_write;
3710 /* start a transaction on a database */
3711 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
3713 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3717 /* start a transaction on a database */
3718 static int ctdb_transaction_fetch_start(struct ctdb_transaction_handle *h)
3720 struct ctdb_record_handle *rh;
3723 struct ctdb_ltdb_header header;
3724 TALLOC_CTX *tmp_ctx;
3725 const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
3727 struct ctdb_db_context *ctdb_db = h->ctdb_db;
3731 key.dptr = discard_const(keyname);
3732 key.dsize = strlen(keyname);
3734 if (!ctdb_db->persistent) {
3735 DEBUG(DEBUG_ERR,(__location__ " Attempted transaction on non-persistent database\n"));
3740 tmp_ctx = talloc_new(h);
3742 rh = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, NULL);
3744 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch_lock database\n"));
3745 talloc_free(tmp_ctx);
3749 status = ctdb_ctrl_transaction_active(ctdb_db->ctdb,
3753 unsigned long int usec = (1000 + random()) % 100000;
3754 DEBUG(DEBUG_DEBUG, (__location__ " transaction is active "
3755 "on db_id[0x%08x]. waiting for %lu "
3757 ctdb_db->db_id, usec));
3758 talloc_free(tmp_ctx);
3764 * store the pid in the database:
3765 * it is not enough that the node is dmaster...
3768 data.dptr = (unsigned char *)&pid;
3769 data.dsize = sizeof(pid_t);
3771 rh->header.dmaster = ctdb_db->ctdb->pnn;
3772 ret = ctdb_ltdb_store(ctdb_db, key, &(rh->header), data);
3774 DEBUG(DEBUG_ERR, (__location__ " Failed to store pid in "
3775 "transaction record\n"));
3776 talloc_free(tmp_ctx);
3782 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
3784 DEBUG(DEBUG_ERR,(__location__ " Failed to start tdb transaction\n"));
3785 talloc_free(tmp_ctx);
3789 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, &data);
3791 DEBUG(DEBUG_ERR,(__location__ " Failed to re-fetch transaction "
3792 "lock record inside transaction\n"));
3793 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3794 talloc_free(tmp_ctx);
3798 if (header.dmaster != ctdb_db->ctdb->pnn) {
3799 DEBUG(DEBUG_DEBUG,(__location__ " not dmaster any more on "
3800 "transaction lock record\n"));
3801 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3802 talloc_free(tmp_ctx);
3806 if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
3807 DEBUG(DEBUG_DEBUG, (__location__ " my pid is not stored in "
3808 "the transaction lock record\n"));
3809 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
3810 talloc_free(tmp_ctx);
3814 talloc_free(tmp_ctx);
3820 /* start a transaction on a database */
3821 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
3822 TALLOC_CTX *mem_ctx)
3824 struct ctdb_transaction_handle *h;
3827 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
3829 DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
3833 h->ctdb_db = ctdb_db;
3835 ret = ctdb_transaction_fetch_start(h);
3841 talloc_set_destructor(h, ctdb_transaction_destructor);
3849 fetch a record inside a transaction
3851 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
3852 TALLOC_CTX *mem_ctx,
3853 TDB_DATA key, TDB_DATA *data)
3855 struct ctdb_ltdb_header header;
3858 ZERO_STRUCT(header);
3860 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
3861 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3862 /* record doesn't exist yet */
3871 if (!h->in_replay) {
3872 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
3873 if (h->m_all == NULL) {
3874 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3883 stores a record inside a transaction
3885 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
3886 TDB_DATA key, TDB_DATA data)
3888 TALLOC_CTX *tmp_ctx = talloc_new(h);
3889 struct ctdb_ltdb_header header;
3893 ZERO_STRUCT(header);
3895 /* we need the header so we can update the RSN */
3896 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
3897 if (ret == -1 && header.dmaster == (uint32_t)-1) {
3898 /* the record doesn't exist - create one with us as dmaster.
3899 This is only safe because we are in a transaction and this
3900 is a persistent database */
3901 ZERO_STRUCT(header);
3902 } else if (ret != 0) {
3903 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
3904 talloc_free(tmp_ctx);
3908 if (data.dsize == olddata.dsize &&
3909 memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
3910 /* save writing the same data */
3911 talloc_free(tmp_ctx);
3915 header.dmaster = h->ctdb_db->ctdb->pnn;
3918 if (!h->in_replay) {
3919 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
3920 if (h->m_all == NULL) {
3921 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3922 talloc_free(tmp_ctx);
3927 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
3928 if (h->m_write == NULL) {
3929 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
3930 talloc_free(tmp_ctx);
3934 ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
3936 talloc_free(tmp_ctx);
3942 replay a transaction
3944 static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
3947 struct ctdb_rec_data *rec = NULL;
3949 h->in_replay = true;
3950 talloc_free(h->m_write);
3953 ret = ctdb_transaction_fetch_start(h);
3958 for (i=0;i<h->m_all->count;i++) {
3961 rec = ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
3963 DEBUG(DEBUG_ERR, (__location__ " Out of records in ctdb_replay_transaction?\n"));
3967 if (rec->reqid == 0) {
3969 if (ctdb_transaction_store(h, key, data) != 0) {
3974 TALLOC_CTX *tmp_ctx = talloc_new(h);
3976 if (ctdb_transaction_fetch(h, tmp_ctx, key, &data2) != 0) {
3977 talloc_free(tmp_ctx);
3980 if (data2.dsize != data.dsize ||
3981 memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
3982 /* the record has changed on us - we have to give up */
3983 talloc_free(tmp_ctx);
3986 talloc_free(tmp_ctx);
3993 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3999 commit a transaction
4001 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
4005 struct ctdb_context *ctdb = h->ctdb_db->ctdb;
4006 struct timeval timeout;
4007 enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
4009 talloc_set_destructor(h, NULL);
4011 /* our commit strategy is quite complex.
4013 - we first try to commit the changes to all other nodes
4015 - if that works, then we commit locally and we are done
4017 - if a commit on another node fails, then we need to cancel
4018 the transaction, then restart the transaction (thus
4019 opening a window of time for a pending recovery to
4020 complete), then replay the transaction, checking all the
4021 reads and writes (checking that reads give the same data,
4022 and writes succeed). Then we retry the transaction to the
4027 if (h->m_write == NULL) {
4028 /* no changes were made */
4029 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
4034 /* tell ctdbd to commit to the other nodes */
4035 timeout = timeval_current_ofs(1, 0);
4036 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4037 retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY, 0,
4038 ctdb_marshall_finish(h->m_write), NULL, NULL, &status,
4040 if (ret != 0 || status != 0) {
4041 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
4042 DEBUG(DEBUG_NOTICE, (__location__ " transaction commit%s failed"
4043 ", retrying after 1 second...\n",
4044 (retries==0)?"":"retry "));
4048 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4050 /* work out what error code we will give if we
4051 have to fail the operation */
4052 switch ((enum ctdb_trans2_commit_error)status) {
4053 case CTDB_TRANS2_COMMIT_SUCCESS:
4054 case CTDB_TRANS2_COMMIT_SOMEFAIL:
4055 case CTDB_TRANS2_COMMIT_TIMEOUT:
4056 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4058 case CTDB_TRANS2_COMMIT_ALLFAIL:
4059 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
4064 if (++retries == 100) {
4065 DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
4066 h->ctdb_db->db_id, retries, (unsigned)failure_control));
4067 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4068 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4069 tdb_null, NULL, NULL, NULL, NULL, NULL);
4074 if (ctdb_replay_transaction(h) != 0) {
4075 DEBUG(DEBUG_ERR, (__location__ " Failed to replay "
4076 "transaction on db 0x%08x, "
4077 "failure control =%u\n",
4079 (unsigned)failure_control));
4080 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4081 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4082 tdb_null, NULL, NULL, NULL, NULL, NULL);
4088 failure_control = CTDB_CONTROL_TRANS2_ERROR;
4091 /* do the real commit locally */
4092 ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
4094 DEBUG(DEBUG_ERR, (__location__ " Failed to commit transaction "
4095 "on db id 0x%08x locally, "
4096 "failure_control=%u\n",
4098 (unsigned)failure_control));
4099 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4100 failure_control, CTDB_CTRL_FLAG_NOREPLY,
4101 tdb_null, NULL, NULL, NULL, NULL, NULL);
4106 /* tell ctdbd that we are finished with our local commit */
4107 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
4108 CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
4109 tdb_null, NULL, NULL, NULL, NULL, NULL);
4115 recovery daemon ping to main daemon
4117 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
4122 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
4123 ctdb, NULL, &res, NULL, NULL);
4124 if (ret != 0 || res != 0) {
4125 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
4132 /* When forking the main daemon and the child process needs to connect
4133 * back to the daemon as a client process, this function can be used
4134 * to change the ctdb context from daemon into client mode. The child
4135 * process must be created using ctdb_fork() and not fork() -
4136 * ctdb_fork() does some necessary housekeeping.
4138 int switch_from_server_to_client(struct ctdb_context *ctdb, const char *fmt, ...)
4143 /* Add extra information so we can identify this in the logs */
4145 debug_extra = talloc_strdup_append(talloc_vasprintf(NULL, fmt, ap), ":");
4148 /* get a new event context */
4149 ctdb->ev = event_context_init(ctdb);
4150 tevent_loop_allow_nesting(ctdb->ev);
4152 /* Connect to main CTDB daemon */
4153 ret = ctdb_socket_connect(ctdb);
4155 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
4159 ctdb->can_send_controls = true;
4165 get the status of running the monitor eventscripts: NULL means never run.
4167 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
4168 struct timeval timeout, uint32_t destnode,
4169 TALLOC_CTX *mem_ctx, enum ctdb_eventscript_call type,
4170 struct ctdb_scripts_wire **scripts)
4173 TDB_DATA outdata, indata;
4175 uint32_t uinttype = type;
4177 indata.dptr = (uint8_t *)&uinttype;
4178 indata.dsize = sizeof(uinttype);
4180 ret = ctdb_control(ctdb, destnode, 0,
4181 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, indata,
4182 mem_ctx, &outdata, &res, &timeout, NULL);
4183 if (ret != 0 || res != 0) {
4184 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
4188 if (outdata.dsize == 0) {
4191 *scripts = (struct ctdb_scripts_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4192 talloc_free(outdata.dptr);
4199 tell the main daemon how long it took to lock the reclock file
4201 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
4207 data.dptr = (uint8_t *)&latency;
4208 data.dsize = sizeof(latency);
4210 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
4211 ctdb, NULL, &res, NULL, NULL);
4212 if (ret != 0 || res != 0) {
4213 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
4221 get the name of the reclock file
4223 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
4224 uint32_t destnode, TALLOC_CTX *mem_ctx,
4231 ret = ctdb_control(ctdb, destnode, 0,
4232 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
4233 mem_ctx, &data, &res, &timeout, NULL);
4234 if (ret != 0 || res != 0) {
4238 if (data.dsize == 0) {
4241 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
4243 talloc_free(data.dptr);
4249 set the reclock filename for a node
4251 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
4257 if (reclock == NULL) {
4261 data.dsize = strlen(reclock) + 1;
4262 data.dptr = discard_const(reclock);
4265 ret = ctdb_control(ctdb, destnode, 0,
4266 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
4267 NULL, NULL, &res, &timeout, NULL);
4268 if (ret != 0 || res != 0) {
4269 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
4279 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4284 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
4285 ctdb, NULL, &res, &timeout, NULL);
4286 if (ret != 0 || res != 0) {
4287 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
4297 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4301 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
4302 ctdb, NULL, NULL, &timeout, NULL);
4304 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
4312 set the natgw state for a node
4314 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
4320 data.dsize = sizeof(natgwstate);
4321 data.dptr = (uint8_t *)&natgwstate;
4323 ret = ctdb_control(ctdb, destnode, 0,
4324 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
4325 NULL, NULL, &res, &timeout, NULL);
4326 if (ret != 0 || res != 0) {
4327 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
4335 set the lmaster role for a node
4337 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
4343 data.dsize = sizeof(lmasterrole);
4344 data.dptr = (uint8_t *)&lmasterrole;
4346 ret = ctdb_control(ctdb, destnode, 0,
4347 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
4348 NULL, NULL, &res, &timeout, NULL);
4349 if (ret != 0 || res != 0) {
4350 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
4358 set the recmaster role for a node
4360 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
4366 data.dsize = sizeof(recmasterrole);
4367 data.dptr = (uint8_t *)&recmasterrole;
4369 ret = ctdb_control(ctdb, destnode, 0,
4370 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
4371 NULL, NULL, &res, &timeout, NULL);
4372 if (ret != 0 || res != 0) {
4373 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
4380 /* enable an eventscript
4382 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4388 data.dsize = strlen(script) + 1;
4389 data.dptr = discard_const(script);
4391 ret = ctdb_control(ctdb, destnode, 0,
4392 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
4393 NULL, NULL, &res, &timeout, NULL);
4394 if (ret != 0 || res != 0) {
4395 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
4402 /* disable an eventscript
4404 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4410 data.dsize = strlen(script) + 1;
4411 data.dptr = discard_const(script);
4413 ret = ctdb_control(ctdb, destnode, 0,
4414 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
4415 NULL, NULL, &res, &timeout, NULL);
4416 if (ret != 0 || res != 0) {
4417 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
4425 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime)
4431 data.dsize = sizeof(*bantime);
4432 data.dptr = (uint8_t *)bantime;
4434 ret = ctdb_control(ctdb, destnode, 0,
4435 CTDB_CONTROL_SET_BAN_STATE, 0, data,
4436 NULL, NULL, &res, &timeout, NULL);
4437 if (ret != 0 || res != 0) {
4438 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4446 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime)
4451 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4453 ret = ctdb_control(ctdb, destnode, 0,
4454 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
4455 tmp_ctx, &outdata, &res, &timeout, NULL);
4456 if (ret != 0 || res != 0) {
4457 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4458 talloc_free(tmp_ctx);
4462 *bantime = (struct ctdb_ban_time *)talloc_steal(mem_ctx, outdata.dptr);
4463 talloc_free(tmp_ctx);
4469 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
4474 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4476 data.dptr = (uint8_t*)db_prio;
4477 data.dsize = sizeof(*db_prio);
4479 ret = ctdb_control(ctdb, destnode, 0,
4480 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
4481 tmp_ctx, NULL, &res, &timeout, NULL);
4482 if (ret != 0 || res != 0) {
4483 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4484 talloc_free(tmp_ctx);
4488 talloc_free(tmp_ctx);
4493 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
4498 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4500 data.dptr = (uint8_t*)&db_id;
4501 data.dsize = sizeof(db_id);
4503 ret = ctdb_control(ctdb, destnode, 0,
4504 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
4505 tmp_ctx, NULL, &res, &timeout, NULL);
4506 if (ret != 0 || res < 0) {
4507 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_db_priority failed\n"));
4508 talloc_free(tmp_ctx);
4516 talloc_free(tmp_ctx);
4521 int ctdb_ctrl_getstathistory(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_statistics_wire **stats)
4527 ret = ctdb_control(ctdb, destnode, 0,
4528 CTDB_CONTROL_GET_STAT_HISTORY, 0, tdb_null,
4529 mem_ctx, &outdata, &res, &timeout, NULL);
4530 if (ret != 0 || res != 0 || outdata.dsize == 0) {
4531 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getstathistory failed ret:%d res:%d\n", ret, res));
4535 *stats = (struct ctdb_statistics_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4536 talloc_free(outdata.dptr);
4541 struct ctdb_ltdb_header *ctdb_header_from_record_handle(struct ctdb_record_handle *h)
4551 struct ctdb_client_control_state *
4552 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)
4554 struct ctdb_client_control_state *handle;
4555 struct ctdb_marshall_buffer *m;
4556 struct ctdb_rec_data *rec;
4559 m = talloc_zero(mem_ctx, struct ctdb_marshall_buffer);
4561 DEBUG(DEBUG_ERR, ("Failed to allocate marshall buffer for update record\n"));
4565 m->db_id = ctdb_db->db_id;
4567 rec = ctdb_marshall_record(m, 0, key, header, data);
4569 DEBUG(DEBUG_ERR,("Failed to marshall record for update record\n"));
4573 m = talloc_realloc_size(mem_ctx, m, rec->length + offsetof(struct ctdb_marshall_buffer, data));
4575 DEBUG(DEBUG_CRIT,(__location__ " Failed to expand recdata\n"));
4580 memcpy((uint8_t *)m + offsetof(struct ctdb_marshall_buffer, data), rec, rec->length);
4583 outdata.dptr = (uint8_t *)m;
4584 outdata.dsize = talloc_get_size(m);
4586 handle = ctdb_control_send(ctdb, destnode, 0,
4587 CTDB_CONTROL_UPDATE_RECORD, 0, outdata,
4588 mem_ctx, &timeout, NULL);
4593 int ctdb_ctrl_updaterecord_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4598 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
4599 if ( (ret != 0) || (res != 0) ){
4600 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_update_record_recv failed\n"));
4608 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)
4610 struct ctdb_client_control_state *state;
4612 state = ctdb_ctrl_updaterecord_send(ctdb, mem_ctx, timeout, destnode, ctdb_db, key, header, data);
4613 return ctdb_ctrl_updaterecord_recv(ctdb, state);
4622 set a database to be readonly
4624 struct ctdb_client_control_state *
4625 ctdb_ctrl_set_db_readonly_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4629 data.dptr = (uint8_t *)&dbid;
4630 data.dsize = sizeof(dbid);
4632 return ctdb_control_send(ctdb, destnode, 0,
4633 CTDB_CONTROL_SET_DB_READONLY, 0, data,
4637 int ctdb_ctrl_set_db_readonly_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4642 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4643 if (ret != 0 || res != 0) {
4644 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_readonly_recv failed ret:%d res:%d\n", ret, res));
4651 int ctdb_ctrl_set_db_readonly(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4653 struct ctdb_client_control_state *state;
4655 state = ctdb_ctrl_set_db_readonly_send(ctdb, destnode, dbid);
4656 return ctdb_ctrl_set_db_readonly_recv(ctdb, state);
4660 set a database to be sticky
4662 struct ctdb_client_control_state *
4663 ctdb_ctrl_set_db_sticky_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4667 data.dptr = (uint8_t *)&dbid;
4668 data.dsize = sizeof(dbid);
4670 return ctdb_control_send(ctdb, destnode, 0,
4671 CTDB_CONTROL_SET_DB_STICKY, 0, data,
4675 int ctdb_ctrl_set_db_sticky_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4680 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4681 if (ret != 0 || res != 0) {
4682 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_sticky_recv failed ret:%d res:%d\n", ret, res));
4689 int ctdb_ctrl_set_db_sticky(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4691 struct ctdb_client_control_state *state;
4693 state = ctdb_ctrl_set_db_sticky_send(ctdb, destnode, dbid);
4694 return ctdb_ctrl_set_db_sticky_recv(ctdb, state);