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/>.
22 #include "system/network.h"
23 #include "system/filesys.h"
24 #include "system/locale.h"
27 /* Allow use of deprecated function tevent_loop_allow_nesting() */
28 #define TEVENT_DEPRECATED
32 #include "lib/tdb_wrap/tdb_wrap.h"
33 #include "lib/util/dlinklist.h"
34 #include "lib/util/time.h"
35 #include "lib/util/debug.h"
36 #include "lib/util/samba_util.h"
38 #include "ctdb_logging.h"
39 #include "ctdb_private.h"
40 #include "ctdb_client.h"
42 #include "common/reqid.h"
43 #include "common/system.h"
44 #include "common/common.h"
47 allocate a packet for use in client<->daemon communication
49 struct ctdb_req_header *_ctdbd_allocate_pkt(struct ctdb_context *ctdb,
51 enum ctdb_operation operation,
52 size_t length, size_t slength,
56 struct ctdb_req_header *hdr;
58 length = MAX(length, slength);
59 size = (length+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
61 hdr = (struct ctdb_req_header *)talloc_zero_size(mem_ctx, size);
63 DEBUG(DEBUG_ERR,("Unable to allocate packet for operation %u of length %u\n",
64 operation, (unsigned)length));
67 talloc_set_name_const(hdr, type);
69 hdr->operation = operation;
70 hdr->ctdb_magic = CTDB_MAGIC;
71 hdr->ctdb_version = CTDB_PROTOCOL;
72 hdr->srcnode = ctdb->pnn;
74 hdr->generation = ctdb->vnn_map->generation;
81 local version of ctdb_call
83 int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
84 struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx,
85 TDB_DATA *data, bool updatetdb)
87 struct ctdb_call_info *c;
88 struct ctdb_registered_call *fn;
89 struct ctdb_context *ctdb = ctdb_db->ctdb;
91 c = talloc(ctdb, struct ctdb_call_info);
92 CTDB_NO_MEMORY(ctdb, c);
95 c->call_data = &call->call_data;
96 c->record_data.dptr = talloc_memdup(c, data->dptr, data->dsize);
97 c->record_data.dsize = data->dsize;
98 CTDB_NO_MEMORY(ctdb, c->record_data.dptr);
100 c->reply_data = NULL;
104 for (fn=ctdb_db->calls;fn;fn=fn->next) {
105 if (fn->id == call->call_id) break;
108 ctdb_set_error(ctdb, "Unknown call id %u\n", call->call_id);
113 if (fn->fn(c) != 0) {
114 ctdb_set_error(ctdb, "ctdb_call %u failed\n", call->call_id);
119 /* we need to force the record to be written out if this was a remote access */
120 if (c->new_data == NULL) {
121 c->new_data = &c->record_data;
124 if (c->new_data && updatetdb) {
125 /* XXX check that we always have the lock here? */
126 if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
127 ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
134 call->reply_data = *c->reply_data;
136 talloc_steal(call, call->reply_data.dptr);
137 talloc_set_name_const(call->reply_data.dptr, __location__);
139 call->reply_data.dptr = NULL;
140 call->reply_data.dsize = 0;
142 call->status = c->status;
151 queue a packet for sending from client to daemon
153 static int ctdb_client_queue_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
155 return ctdb_queue_send(ctdb->daemon.queue, (uint8_t *)hdr, hdr->length);
160 called when a CTDB_REPLY_CALL packet comes in in the client
162 This packet comes in response to a CTDB_REQ_CALL request packet. It
163 contains any reply data from the call
165 static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
167 struct ctdb_reply_call_old *c = (struct ctdb_reply_call_old *)hdr;
168 struct ctdb_client_call_state *state;
170 state = reqid_find(ctdb->idr, hdr->reqid, struct ctdb_client_call_state);
172 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
176 if (hdr->reqid != state->reqid) {
177 /* we found a record but it was the wrong one */
178 DEBUG(DEBUG_ERR, ("Dropped client call reply with reqid:%u\n",hdr->reqid));
182 state->call->reply_data.dptr = c->data;
183 state->call->reply_data.dsize = c->datalen;
184 state->call->status = c->status;
186 talloc_steal(state, c);
188 state->state = CTDB_CALL_DONE;
190 if (state->async.fn) {
191 state->async.fn(state);
195 void ctdb_request_message(struct ctdb_context *ctdb,
196 struct ctdb_req_header *hdr)
198 struct ctdb_req_message_old *c = (struct ctdb_req_message_old *)hdr;
201 data.dsize = c->datalen;
202 data.dptr = talloc_memdup(c, &c->data[0], c->datalen);
203 if (data.dptr == NULL) {
204 DEBUG(DEBUG_ERR, (__location__ " Memory allocation failure\n"));
208 srvid_dispatch(ctdb->srv, c->srvid, CTDB_SRVID_ALL, data);
211 static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
214 this is called in the client, when data comes in from the daemon
216 void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
218 struct ctdb_context *ctdb = talloc_get_type(args, struct ctdb_context);
219 struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
222 /* place the packet as a child of a tmp_ctx. We then use
223 talloc_free() below to free it. If any of the calls want
224 to keep it, then they will steal it somewhere else, and the
225 talloc_free() will be a no-op */
226 tmp_ctx = talloc_new(ctdb);
227 talloc_steal(tmp_ctx, hdr);
230 DEBUG(DEBUG_CRIT,("Daemon has exited - shutting down client\n"));
234 if (cnt < sizeof(*hdr)) {
235 DEBUG(DEBUG_CRIT,("Bad packet length %u in client\n", (unsigned)cnt));
238 if (cnt != hdr->length) {
239 ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n",
240 (unsigned)hdr->length, (unsigned)cnt);
244 if (hdr->ctdb_magic != CTDB_MAGIC) {
245 ctdb_set_error(ctdb, "Non CTDB packet rejected in client\n");
249 if (hdr->ctdb_version != CTDB_PROTOCOL) {
250 ctdb_set_error(ctdb, "Bad CTDB version 0x%x rejected in client\n", hdr->ctdb_version);
254 switch (hdr->operation) {
255 case CTDB_REPLY_CALL:
256 ctdb_client_reply_call(ctdb, hdr);
259 case CTDB_REQ_MESSAGE:
260 ctdb_request_message(ctdb, hdr);
263 case CTDB_REPLY_CONTROL:
264 ctdb_client_reply_control(ctdb, hdr);
268 DEBUG(DEBUG_CRIT,("bogus operation code:%u\n",hdr->operation));
272 talloc_free(tmp_ctx);
276 connect to a unix domain socket
278 int ctdb_socket_connect(struct ctdb_context *ctdb)
280 struct sockaddr_un addr;
282 memset(&addr, 0, sizeof(addr));
283 addr.sun_family = AF_UNIX;
284 strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path)-1);
286 ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
287 if (ctdb->daemon.sd == -1) {
288 DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
292 if (connect(ctdb->daemon.sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
293 close(ctdb->daemon.sd);
294 ctdb->daemon.sd = -1;
295 DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
299 set_nonblocking(ctdb->daemon.sd);
300 set_close_on_exec(ctdb->daemon.sd);
302 ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd,
304 ctdb_client_read_cb, ctdb, "to-ctdbd");
309 struct ctdb_record_handle {
310 struct ctdb_db_context *ctdb_db;
313 struct ctdb_ltdb_header header;
318 make a recv call to the local ctdb daemon - called from client context
320 This is called when the program wants to wait for a ctdb_call to complete and get the
321 results. This call will block unless the call has already completed.
323 int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
329 while (state->state < CTDB_CALL_DONE) {
330 tevent_loop_once(state->ctdb_db->ctdb->ev);
332 if (state->state != CTDB_CALL_DONE) {
333 DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
338 if (state->call->reply_data.dsize) {
339 call->reply_data.dptr = talloc_memdup(state->ctdb_db,
340 state->call->reply_data.dptr,
341 state->call->reply_data.dsize);
342 call->reply_data.dsize = state->call->reply_data.dsize;
344 call->reply_data.dptr = NULL;
345 call->reply_data.dsize = 0;
347 call->status = state->call->status;
357 destroy a ctdb_call in client
359 static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)
361 reqid_remove(state->ctdb_db->ctdb->idr, state->reqid);
366 construct an event driven local ctdb_call
368 this is used so that locally processed ctdb_call requests are processed
369 in an event driven manner
371 static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db,
372 struct ctdb_call *call,
373 struct ctdb_ltdb_header *header,
376 struct ctdb_client_call_state *state;
377 struct ctdb_context *ctdb = ctdb_db->ctdb;
380 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
381 CTDB_NO_MEMORY_NULL(ctdb, state);
382 state->call = talloc_zero(state, struct ctdb_call);
383 CTDB_NO_MEMORY_NULL(ctdb, state->call);
385 talloc_steal(state, data->dptr);
387 state->state = CTDB_CALL_DONE;
388 *(state->call) = *call;
389 state->ctdb_db = ctdb_db;
391 ret = ctdb_call_local(ctdb_db, state->call, header, state, data, true);
393 DEBUG(DEBUG_DEBUG,("ctdb_call_local() failed, ignoring return code %d\n", ret));
400 make a ctdb call to the local daemon - async send. Called from client context.
402 This constructs a ctdb_call request and queues it for processing.
403 This call never blocks.
405 struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
406 struct ctdb_call *call)
408 struct ctdb_client_call_state *state;
409 struct ctdb_context *ctdb = ctdb_db->ctdb;
410 struct ctdb_ltdb_header header;
414 struct ctdb_req_call_old *c;
416 /* if the domain socket is not yet open, open it */
417 if (ctdb->daemon.sd==-1) {
418 ctdb_socket_connect(ctdb);
421 ret = ctdb_ltdb_lock(ctdb_db, call->key);
423 DEBUG(DEBUG_ERR,(__location__ " Failed to get chainlock\n"));
427 ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
429 if ((call->flags & CTDB_IMMEDIATE_MIGRATION) && (header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
433 if (ret == 0 && header.dmaster == ctdb->pnn) {
434 state = ctdb_client_call_local_send(ctdb_db, call, &header, &data);
435 talloc_free(data.dptr);
436 ctdb_ltdb_unlock(ctdb_db, call->key);
440 ctdb_ltdb_unlock(ctdb_db, call->key);
441 talloc_free(data.dptr);
443 state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
445 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state\n"));
448 state->call = talloc_zero(state, struct ctdb_call);
449 if (state->call == NULL) {
450 DEBUG(DEBUG_ERR, (__location__ " failed to allocate state->call\n"));
454 len = offsetof(struct ctdb_req_call_old, data) + call->key.dsize + call->call_data.dsize;
455 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CALL, len, struct ctdb_req_call_old);
457 DEBUG(DEBUG_ERR, (__location__ " failed to allocate packet\n"));
461 state->reqid = reqid_new(ctdb->idr, state);
462 state->ctdb_db = ctdb_db;
463 talloc_set_destructor(state, ctdb_client_call_destructor);
465 c->hdr.reqid = state->reqid;
466 c->flags = call->flags;
467 c->db_id = ctdb_db->db_id;
468 c->callid = call->call_id;
470 c->keylen = call->key.dsize;
471 c->calldatalen = call->call_data.dsize;
472 memcpy(&c->data[0], call->key.dptr, call->key.dsize);
473 memcpy(&c->data[call->key.dsize],
474 call->call_data.dptr, call->call_data.dsize);
475 *(state->call) = *call;
476 state->call->call_data.dptr = &c->data[call->key.dsize];
477 state->call->key.dptr = &c->data[0];
479 state->state = CTDB_CALL_WAIT;
482 ctdb_client_queue_pkt(ctdb, &c->hdr);
489 full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
491 int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
493 struct ctdb_client_call_state *state;
495 state = ctdb_call_send(ctdb_db, call);
496 return ctdb_call_recv(state, call);
501 tell the daemon what messaging srvid we will use, and register the message
502 handler function in the client
504 int ctdb_client_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid,
505 srvid_handler_fn handler,
511 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid,
512 CTDB_CONTROL_REGISTER_SRVID, 0,
513 tdb_null, NULL, NULL, &status, NULL, NULL);
514 if (res != 0 || status != 0) {
516 ("Failed to register srvid %llu\n",
517 (unsigned long long)srvid));
521 /* also need to register the handler with our own ctdb structure */
522 return srvid_register(ctdb->srv, ctdb, srvid, handler, private_data);
526 tell the daemon we no longer want a srvid
528 int ctdb_client_remove_message_handler(struct ctdb_context *ctdb,
529 uint64_t srvid, void *private_data)
534 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid,
535 CTDB_CONTROL_DEREGISTER_SRVID, 0,
536 tdb_null, NULL, NULL, &status, NULL, NULL);
537 if (res != 0 || status != 0) {
539 ("Failed to deregister srvid %llu\n",
540 (unsigned long long)srvid));
544 /* also need to register the handler with our own ctdb structure */
545 srvid_deregister(ctdb->srv, srvid, private_data);
552 int ctdb_client_check_message_handlers(struct ctdb_context *ctdb, uint64_t *ids, uint32_t num,
555 TDB_DATA indata, outdata;
560 indata.dptr = (uint8_t *)ids;
561 indata.dsize = num * sizeof(*ids);
563 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_CHECK_SRVIDS, 0,
564 indata, ctdb, &outdata, &status, NULL, NULL);
565 if (res != 0 || status != 0) {
566 DEBUG(DEBUG_ERR, (__location__ " failed to check srvids\n"));
570 if (outdata.dsize != num*sizeof(uint8_t)) {
571 DEBUG(DEBUG_ERR, (__location__ " expected %lu bytes, received %zi bytes\n",
572 (long unsigned int)num*sizeof(uint8_t),
574 talloc_free(outdata.dptr);
578 for (i=0; i<num; i++) {
579 result[i] = outdata.dptr[i];
582 talloc_free(outdata.dptr);
587 send a message - from client context
589 int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t pnn,
590 uint64_t srvid, TDB_DATA data)
592 struct ctdb_req_message_old *r;
595 len = offsetof(struct ctdb_req_message_old, data) + data.dsize;
596 r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE,
597 len, struct ctdb_req_message_old);
598 CTDB_NO_MEMORY(ctdb, r);
600 r->hdr.destnode = pnn;
602 r->datalen = data.dsize;
603 memcpy(&r->data[0], data.dptr, data.dsize);
605 res = ctdb_client_queue_pkt(ctdb, &r->hdr);
612 cancel a ctdb_fetch_lock operation, releasing the lock
614 static int fetch_lock_destructor(struct ctdb_record_handle *h)
616 ctdb_ltdb_unlock(h->ctdb_db, h->key);
621 force the migration of a record to this node
623 static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
625 struct ctdb_call call;
627 call.call_id = CTDB_NULL_FUNC;
629 call.flags = CTDB_IMMEDIATE_MIGRATION;
630 return ctdb_call(ctdb_db, &call);
634 try to fetch a readonly copy of a record
637 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)
641 struct ctdb_call call;
644 call.call_id = CTDB_FETCH_WITH_HEADER_FUNC;
645 call.call_data.dptr = NULL;
646 call.call_data.dsize = 0;
648 call.flags = CTDB_WANT_READONLY;
649 ret = ctdb_call(ctdb_db, &call);
654 if (call.reply_data.dsize < sizeof(struct ctdb_ltdb_header)) {
658 *hdr = talloc_memdup(mem_ctx, &call.reply_data.dptr[0], sizeof(struct ctdb_ltdb_header));
660 talloc_free(call.reply_data.dptr);
664 data->dsize = call.reply_data.dsize - sizeof(struct ctdb_ltdb_header);
665 data->dptr = talloc_memdup(mem_ctx, &call.reply_data.dptr[sizeof(struct ctdb_ltdb_header)], data->dsize);
666 if (data->dptr == NULL) {
667 talloc_free(call.reply_data.dptr);
676 get a lock on a record, and return the records data. Blocks until it gets the lock
678 struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
679 TDB_DATA key, TDB_DATA *data)
682 struct ctdb_record_handle *h;
685 procedure is as follows:
687 1) get the chain lock.
688 2) check if we are dmaster
689 3) if we are the dmaster then return handle
690 4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
692 5) when we get the reply, goto (1)
695 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
700 h->ctdb_db = ctdb_db;
702 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
703 if (h->key.dptr == NULL) {
709 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize,
710 (const char *)key.dptr));
713 /* step 1 - get the chain lock */
714 ret = ctdb_ltdb_lock(ctdb_db, key);
716 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
721 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
723 talloc_set_destructor(h, fetch_lock_destructor);
725 ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
727 /* when torturing, ensure we test the remote path */
728 if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
730 h->header.dmaster = (uint32_t)-1;
734 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
736 if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
737 ctdb_ltdb_unlock(ctdb_db, key);
738 ret = ctdb_client_force_migration(ctdb_db, key);
740 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
747 /* if this is a request for read/write and we have delegations
748 we have to revoke all delegations first
750 if ((h->header.dmaster == ctdb_db->ctdb->pnn) &&
751 (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
752 ctdb_ltdb_unlock(ctdb_db, key);
753 ret = ctdb_client_force_migration(ctdb_db, key);
755 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
762 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
767 get a readonly lock on a record, and return the records data. Blocks until it gets the lock
769 struct ctdb_record_handle *
770 ctdb_fetch_readonly_lock(
771 struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
772 TDB_DATA key, TDB_DATA *data,
776 struct ctdb_record_handle *h;
777 struct ctdb_ltdb_header *roheader = NULL;
779 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
784 h->ctdb_db = ctdb_db;
786 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
787 if (h->key.dptr == NULL) {
798 talloc_free(roheader);
801 talloc_free(data->dptr);
805 /* Lock the record/chain */
806 ret = ctdb_ltdb_lock(ctdb_db, key);
808 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
813 talloc_set_destructor(h, fetch_lock_destructor);
815 /* Check if record exists yet in the TDB */
816 ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
818 ctdb_ltdb_unlock(ctdb_db, key);
819 ret = ctdb_client_force_migration(ctdb_db, key);
821 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
828 /* if this is a request for read/write and we have delegations
829 we have to revoke all delegations first
832 && (h->header.dmaster == ctdb_db->ctdb->pnn)
833 && (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
834 ctdb_ltdb_unlock(ctdb_db, key);
835 ret = ctdb_client_force_migration(ctdb_db, key);
837 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
844 /* if we are dmaster, just return the handle */
845 if (h->header.dmaster == ctdb_db->ctdb->pnn) {
849 if (read_only != 0) {
850 TDB_DATA rodata = {NULL, 0};
852 if ((h->header.flags & CTDB_REC_RO_HAVE_READONLY)
853 || (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
857 ctdb_ltdb_unlock(ctdb_db, key);
858 ret = ctdb_client_fetch_readonly(ctdb_db, key, h, &roheader, &rodata);
860 DEBUG(DEBUG_ERR,("ctdb_fetch_readonly_lock: failed. force migration and try again\n"));
861 ret = ctdb_client_force_migration(ctdb_db, key);
863 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
871 if (!(roheader->flags&CTDB_REC_RO_HAVE_READONLY)) {
872 ret = ctdb_client_force_migration(ctdb_db, key);
874 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
882 ret = ctdb_ltdb_lock(ctdb_db, key);
884 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
889 ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
891 ctdb_ltdb_unlock(ctdb_db, key);
893 ret = ctdb_client_force_migration(ctdb_db, key);
895 DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
906 /* we are not dmaster and this was not a request for a readonly lock
907 * so unlock the record, migrate it and try again
909 ctdb_ltdb_unlock(ctdb_db, key);
910 ret = ctdb_client_force_migration(ctdb_db, key);
912 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
920 store some data to the record that was locked with ctdb_fetch_lock()
922 int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
924 if (h->ctdb_db->persistent) {
925 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
929 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
933 non-locking fetch of a record
935 int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
936 TDB_DATA key, TDB_DATA *data)
938 struct ctdb_call call;
941 call.call_id = CTDB_FETCH_FUNC;
942 call.call_data.dptr = NULL;
943 call.call_data.dsize = 0;
946 ret = ctdb_call(ctdb_db, &call);
949 *data = call.reply_data;
950 talloc_steal(mem_ctx, data->dptr);
959 called when a control completes or timesout to invoke the callback
960 function the user provided
962 static void invoke_control_callback(struct tevent_context *ev,
963 struct tevent_timer *te,
964 struct timeval t, void *private_data)
966 struct ctdb_client_control_state *state;
967 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
970 state = talloc_get_type(private_data, struct ctdb_client_control_state);
971 talloc_steal(tmp_ctx, state);
973 ret = ctdb_control_recv(state->ctdb, state, state,
978 DEBUG(DEBUG_DEBUG,("ctdb_control_recv() failed, ignoring return code %d\n", ret));
981 talloc_free(tmp_ctx);
985 called when a CTDB_REPLY_CONTROL packet comes in in the client
987 This packet comes in response to a CTDB_REQ_CONTROL request packet. It
988 contains any reply data from the control
990 static void ctdb_client_reply_control(struct ctdb_context *ctdb,
991 struct ctdb_req_header *hdr)
993 struct ctdb_reply_control_old *c = (struct ctdb_reply_control_old *)hdr;
994 struct ctdb_client_control_state *state;
996 state = reqid_find(ctdb->idr, hdr->reqid, struct ctdb_client_control_state);
998 DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
1002 if (hdr->reqid != state->reqid) {
1003 /* we found a record but it was the wrong one */
1004 DEBUG(DEBUG_ERR, ("Dropped orphaned reply control with reqid:%u\n",hdr->reqid));
1008 state->outdata.dptr = c->data;
1009 state->outdata.dsize = c->datalen;
1010 state->status = c->status;
1012 state->errormsg = talloc_strndup(state,
1013 (char *)&c->data[c->datalen],
1017 /* state->outdata now uses resources from c so we dont want c
1018 to just dissappear from under us while state is still alive
1020 talloc_steal(state, c);
1022 state->state = CTDB_CONTROL_DONE;
1024 /* if we had a callback registered for this control, pull the response
1025 and call the callback.
1027 if (state->async.fn) {
1028 tevent_add_timer(ctdb->ev, state, timeval_zero(),
1029 invoke_control_callback, state);
1035 destroy a ctdb_control in client
1037 static int ctdb_client_control_destructor(struct ctdb_client_control_state *state)
1039 reqid_remove(state->ctdb->idr, state->reqid);
1044 /* time out handler for ctdb_control */
1045 static void control_timeout_func(struct tevent_context *ev,
1046 struct tevent_timer *te,
1047 struct timeval t, void *private_data)
1049 struct ctdb_client_control_state *state = talloc_get_type(private_data, struct ctdb_client_control_state);
1051 DEBUG(DEBUG_ERR,(__location__ " control timed out. reqid:%u opcode:%u "
1052 "dstnode:%u\n", state->reqid, state->c->opcode,
1053 state->c->hdr.destnode));
1055 state->state = CTDB_CONTROL_TIMEOUT;
1057 /* if we had a callback registered for this control, pull the response
1058 and call the callback.
1060 if (state->async.fn) {
1061 tevent_add_timer(state->ctdb->ev, state, timeval_zero(),
1062 invoke_control_callback, state);
1066 /* async version of send control request */
1067 struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb,
1068 uint32_t destnode, uint64_t srvid,
1069 uint32_t opcode, uint32_t flags, TDB_DATA data,
1070 TALLOC_CTX *mem_ctx,
1071 struct timeval *timeout,
1074 struct ctdb_client_control_state *state;
1076 struct ctdb_req_control_old *c;
1083 /* if the domain socket is not yet open, open it */
1084 if (ctdb->daemon.sd==-1) {
1085 ctdb_socket_connect(ctdb);
1088 state = talloc_zero(mem_ctx, struct ctdb_client_control_state);
1089 CTDB_NO_MEMORY_NULL(ctdb, state);
1092 state->reqid = reqid_new(ctdb->idr, state);
1093 state->state = CTDB_CONTROL_WAIT;
1094 state->errormsg = NULL;
1096 talloc_set_destructor(state, ctdb_client_control_destructor);
1098 len = offsetof(struct ctdb_req_control_old, data) + data.dsize;
1099 c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL,
1100 len, struct ctdb_req_control_old);
1102 CTDB_NO_MEMORY_NULL(ctdb, c);
1103 c->hdr.reqid = state->reqid;
1104 c->hdr.destnode = destnode;
1109 c->datalen = data.dsize;
1111 memcpy(&c->data[0], data.dptr, data.dsize);
1115 if (timeout && !timeval_is_zero(timeout)) {
1116 tevent_add_timer(ctdb->ev, state, *timeout,
1117 control_timeout_func, state);
1120 ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
1126 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
1135 /* async version of receive control reply */
1136 int ctdb_control_recv(struct ctdb_context *ctdb,
1137 struct ctdb_client_control_state *state,
1138 TALLOC_CTX *mem_ctx,
1139 TDB_DATA *outdata, int32_t *status, char **errormsg)
1141 TALLOC_CTX *tmp_ctx;
1143 if (status != NULL) {
1146 if (errormsg != NULL) {
1150 if (state == NULL) {
1154 /* prevent double free of state */
1155 tmp_ctx = talloc_new(ctdb);
1156 talloc_steal(tmp_ctx, state);
1158 /* loop one event at a time until we either timeout or the control
1161 while (state->state == CTDB_CONTROL_WAIT) {
1162 tevent_loop_once(ctdb->ev);
1165 if (state->state != CTDB_CONTROL_DONE) {
1166 DEBUG(DEBUG_ERR,(__location__ " ctdb_control_recv failed\n"));
1167 if (state->async.fn) {
1168 state->async.fn(state);
1170 talloc_free(tmp_ctx);
1174 if (state->errormsg) {
1175 DEBUG(DEBUG_ERR,("ctdb_control error: '%s'\n", state->errormsg));
1177 (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
1179 if (state->async.fn) {
1180 state->async.fn(state);
1182 talloc_free(tmp_ctx);
1183 return (status == 0 ? -1 : state->status);
1187 *outdata = state->outdata;
1188 outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
1192 *status = state->status;
1195 if (state->async.fn) {
1196 state->async.fn(state);
1199 talloc_free(tmp_ctx);
1206 send a ctdb control message
1207 timeout specifies how long we should wait for a reply.
1208 if timeout is NULL we wait indefinitely
1210 int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
1211 uint32_t opcode, uint32_t flags, TDB_DATA data,
1212 TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
1213 struct timeval *timeout,
1216 struct ctdb_client_control_state *state;
1218 state = ctdb_control_send(ctdb, destnode, srvid, opcode,
1219 flags, data, mem_ctx,
1222 /* FIXME: Error conditions in ctdb_control_send return NULL without
1223 * setting errormsg. So, there is no way to distinguish between sucess
1224 * and failure when CTDB_CTRL_FLAG_NOREPLY is set */
1225 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
1226 if (status != NULL) {
1232 return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
1240 a process exists call. Returns 0 if process exists, -1 otherwise
1242 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
1248 data.dptr = (uint8_t*)&pid;
1249 data.dsize = sizeof(pid);
1251 ret = ctdb_control(ctdb, destnode, 0,
1252 CTDB_CONTROL_PROCESS_EXISTS, 0, data,
1253 NULL, NULL, &status, NULL, NULL);
1255 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
1263 get remote statistics
1265 int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
1271 ret = ctdb_control(ctdb, destnode, 0,
1272 CTDB_CONTROL_STATISTICS, 0, tdb_null,
1273 ctdb, &data, &res, NULL, NULL);
1274 if (ret != 0 || res != 0) {
1275 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
1279 if (data.dsize != sizeof(struct ctdb_statistics)) {
1280 DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
1281 (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
1285 *status = *(struct ctdb_statistics *)data.dptr;
1286 talloc_free(data.dptr);
1294 int ctdb_ctrl_dbstatistics(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
1295 TALLOC_CTX *mem_ctx, struct ctdb_db_statistics **dbstat)
1298 TDB_DATA indata, outdata;
1300 struct ctdb_db_statistics *wire, *s;
1304 indata.dptr = (uint8_t *)&dbid;
1305 indata.dsize = sizeof(dbid);
1307 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DB_STATISTICS,
1308 0, indata, ctdb, &outdata, &res, NULL, NULL);
1309 if (ret != 0 || res != 0) {
1310 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for dbstatistics failed\n"));
1314 if (outdata.dsize < offsetof(struct ctdb_db_statistics, hot_keys_wire)) {
1315 DEBUG(DEBUG_ERR,(__location__ " Wrong dbstatistics size %zi - expected >= %lu\n",
1317 (long unsigned int)sizeof(struct ctdb_statistics)));
1321 s = talloc_zero(mem_ctx, struct ctdb_db_statistics);
1323 talloc_free(outdata.dptr);
1324 CTDB_NO_MEMORY(ctdb, s);
1327 wire = (struct ctdb_db_statistics *)outdata.dptr;
1328 memcpy(s, wire, offsetof(struct ctdb_db_statistics, hot_keys_wire));
1329 ptr = &wire->hot_keys_wire[0];
1330 for (i=0; i<wire->num_hot_keys; i++) {
1331 s->hot_keys[i].key.dptr = talloc_size(mem_ctx, s->hot_keys[i].key.dsize);
1332 if (s->hot_keys[i].key.dptr == NULL) {
1333 talloc_free(outdata.dptr);
1334 CTDB_NO_MEMORY(ctdb, s->hot_keys[i].key.dptr);
1337 memcpy(s->hot_keys[i].key.dptr, ptr, s->hot_keys[i].key.dsize);
1338 ptr += wire->hot_keys[i].key.dsize;
1341 talloc_free(outdata.dptr);
1347 shutdown a remote ctdb node
1349 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1351 struct ctdb_client_control_state *state;
1353 state = ctdb_control_send(ctdb, destnode, 0,
1354 CTDB_CONTROL_SHUTDOWN, 0, tdb_null,
1355 NULL, &timeout, NULL);
1356 if (state == NULL) {
1357 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
1365 get vnn map from a remote node
1367 int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
1372 struct ctdb_vnn_map_wire *map;
1374 ret = ctdb_control(ctdb, destnode, 0,
1375 CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
1376 mem_ctx, &outdata, &res, &timeout, NULL);
1377 if (ret != 0 || res != 0) {
1378 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
1382 map = (struct ctdb_vnn_map_wire *)outdata.dptr;
1383 if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
1384 outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
1385 DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
1389 (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
1390 CTDB_NO_MEMORY(ctdb, *vnnmap);
1391 (*vnnmap)->generation = map->generation;
1392 (*vnnmap)->size = map->size;
1393 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
1395 CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
1396 memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
1397 talloc_free(outdata.dptr);
1404 get the recovery mode of a remote node
1406 struct ctdb_client_control_state *
1407 ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
1409 return ctdb_control_send(ctdb, destnode, 0,
1410 CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
1411 mem_ctx, &timeout, NULL);
1414 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
1419 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1421 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
1426 *recmode = (uint32_t)res;
1432 int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
1434 struct ctdb_client_control_state *state;
1436 state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
1437 return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
1444 set the recovery mode of a remote node
1446 int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
1452 data.dsize = sizeof(uint32_t);
1453 data.dptr = (unsigned char *)&recmode;
1455 ret = ctdb_control(ctdb, destnode, 0,
1456 CTDB_CONTROL_SET_RECMODE, 0, data,
1457 NULL, NULL, &res, &timeout, NULL);
1458 if (ret != 0 || res != 0) {
1459 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
1469 get the recovery master of a remote node
1471 struct ctdb_client_control_state *
1472 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
1473 struct timeval timeout, uint32_t destnode)
1475 return ctdb_control_send(ctdb, destnode, 0,
1476 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
1477 mem_ctx, &timeout, NULL);
1480 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
1485 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1487 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
1492 *recmaster = (uint32_t)res;
1498 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
1500 struct ctdb_client_control_state *state;
1502 state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
1503 return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
1508 set the recovery master of a remote node
1510 int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
1517 data.dsize = sizeof(uint32_t);
1518 data.dptr = (unsigned char *)&recmaster;
1520 ret = ctdb_control(ctdb, destnode, 0,
1521 CTDB_CONTROL_SET_RECMASTER, 0, data,
1522 NULL, NULL, &res, &timeout, NULL);
1523 if (ret != 0 || res != 0) {
1524 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
1533 get a list of databases off a remote node
1535 int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1536 TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
1542 ret = ctdb_control(ctdb, destnode, 0,
1543 CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
1544 mem_ctx, &outdata, &res, &timeout, NULL);
1545 if (ret != 0 || res != 0) {
1546 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
1550 *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1551 talloc_free(outdata.dptr);
1557 get a list of nodes (vnn and flags ) from a remote node
1559 int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
1560 struct timeval timeout, uint32_t destnode,
1561 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1567 ret = ctdb_control(ctdb, destnode, 0,
1568 CTDB_CONTROL_GET_NODEMAP, 0, tdb_null,
1569 mem_ctx, &outdata, &res, &timeout, NULL);
1570 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1571 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
1575 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1576 talloc_free(outdata.dptr);
1581 load nodes file on a remote node and return as a node map
1583 int ctdb_ctrl_getnodesfile(struct ctdb_context *ctdb,
1584 struct timeval timeout, uint32_t destnode,
1585 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
1591 ret = ctdb_control(ctdb, destnode, 0,
1592 CTDB_CONTROL_GET_NODES_FILE, 0, tdb_null,
1593 mem_ctx, &outdata, &res, &timeout, NULL);
1594 if (ret != 0 || res != 0 || outdata.dsize == 0) {
1595 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
1599 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1600 talloc_free(outdata.dptr);
1606 drop the transport, reload the nodes file and restart the transport
1608 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
1609 struct timeval timeout, uint32_t destnode)
1614 ret = ctdb_control(ctdb, destnode, 0,
1615 CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
1616 NULL, NULL, &res, &timeout, NULL);
1617 if (ret != 0 || res != 0) {
1618 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
1627 set vnn map on a node
1629 int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1630 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
1635 struct ctdb_vnn_map_wire *map;
1638 len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
1639 map = talloc_size(mem_ctx, len);
1640 CTDB_NO_MEMORY(ctdb, map);
1642 map->generation = vnnmap->generation;
1643 map->size = vnnmap->size;
1644 memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
1647 data.dptr = (uint8_t *)map;
1649 ret = ctdb_control(ctdb, destnode, 0,
1650 CTDB_CONTROL_SETVNNMAP, 0, data,
1651 NULL, NULL, &res, &timeout, NULL);
1652 if (ret != 0 || res != 0) {
1653 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
1664 async send for pull database
1666 struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
1667 struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
1668 uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
1671 struct ctdb_control_pulldb *pull;
1672 struct ctdb_client_control_state *state;
1674 pull = talloc(mem_ctx, struct ctdb_control_pulldb);
1675 CTDB_NO_MEMORY_NULL(ctdb, pull);
1678 pull->lmaster = lmaster;
1680 indata.dsize = sizeof(struct ctdb_control_pulldb);
1681 indata.dptr = (unsigned char *)pull;
1683 state = ctdb_control_send(ctdb, destnode, 0,
1684 CTDB_CONTROL_PULL_DB, 0, indata,
1685 mem_ctx, &timeout, NULL);
1692 async recv for pull database
1694 int ctdb_ctrl_pulldb_recv(
1695 struct ctdb_context *ctdb,
1696 TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state,
1702 ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
1703 if ( (ret != 0) || (res != 0) ){
1704 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
1712 pull all keys and records for a specific database on a node
1714 int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode,
1715 uint32_t dbid, uint32_t lmaster,
1716 TALLOC_CTX *mem_ctx, struct timeval timeout,
1719 struct ctdb_client_control_state *state;
1721 state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
1724 return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
1729 change dmaster for all keys in the database to the new value
1731 int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1732 TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
1738 indata.dsize = 2*sizeof(uint32_t);
1739 indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
1741 ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
1742 ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
1744 ret = ctdb_control(ctdb, destnode, 0,
1745 CTDB_CONTROL_SET_DMASTER, 0, indata,
1746 NULL, NULL, &res, &timeout, NULL);
1747 if (ret != 0 || res != 0) {
1748 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
1756 ping a node, return number of clients connected
1758 int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
1763 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0,
1764 tdb_null, NULL, NULL, &res, NULL, NULL);
1771 int ctdb_ctrl_get_runstate(struct ctdb_context *ctdb,
1772 struct timeval timeout,
1780 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_RUNSTATE, 0,
1781 tdb_null, ctdb, &outdata, &res, &timeout, NULL);
1782 if (ret != 0 || res != 0) {
1783 DEBUG(DEBUG_ERR,("ctdb_control for get_runstate failed\n"));
1784 return ret != 0 ? ret : res;
1787 if (outdata.dsize != sizeof(uint32_t)) {
1788 DEBUG(DEBUG_ERR,("Invalid return data in get_runstate\n"));
1789 talloc_free(outdata.dptr);
1793 if (runstate != NULL) {
1794 *runstate = *(uint32_t *)outdata.dptr;
1796 talloc_free(outdata.dptr);
1802 find the real path to a ltdb
1804 int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1811 data.dptr = (uint8_t *)&dbid;
1812 data.dsize = sizeof(dbid);
1814 ret = ctdb_control(ctdb, destnode, 0,
1815 CTDB_CONTROL_GETDBPATH, 0, data,
1816 mem_ctx, &data, &res, &timeout, NULL);
1817 if (ret != 0 || res != 0) {
1821 (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1822 if ((*path) == NULL) {
1826 talloc_free(data.dptr);
1832 find the name of a db
1834 int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
1841 data.dptr = (uint8_t *)&dbid;
1842 data.dsize = sizeof(dbid);
1844 ret = ctdb_control(ctdb, destnode, 0,
1845 CTDB_CONTROL_GET_DBNAME, 0, data,
1846 mem_ctx, &data, &res, &timeout, NULL);
1847 if (ret != 0 || res != 0) {
1851 (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1852 if ((*name) == NULL) {
1856 talloc_free(data.dptr);
1862 get the health status of a db
1864 int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
1865 struct timeval timeout,
1867 uint32_t dbid, TALLOC_CTX *mem_ctx,
1868 const char **reason)
1874 data.dptr = (uint8_t *)&dbid;
1875 data.dsize = sizeof(dbid);
1877 ret = ctdb_control(ctdb, destnode, 0,
1878 CTDB_CONTROL_DB_GET_HEALTH, 0, data,
1879 mem_ctx, &data, &res, &timeout, NULL);
1880 if (ret != 0 || res != 0) {
1884 if (data.dsize == 0) {
1889 (*reason) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
1890 if ((*reason) == NULL) {
1894 talloc_free(data.dptr);
1900 * get db sequence number
1902 int ctdb_ctrl_getdbseqnum(struct ctdb_context *ctdb, struct timeval timeout,
1903 uint32_t destnode, uint32_t dbid, uint64_t *seqnum)
1907 TDB_DATA data, outdata;
1909 data.dptr = (uint8_t *)&dbid;
1910 data.dsize = sizeof(uint64_t); /* This is just wrong */
1912 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DB_SEQNUM,
1913 0, data, ctdb, &outdata, &res, &timeout, NULL);
1914 if (ret != 0 || res != 0) {
1915 DEBUG(DEBUG_ERR,("ctdb_control for getdbesqnum failed\n"));
1919 if (outdata.dsize != sizeof(uint64_t)) {
1920 DEBUG(DEBUG_ERR,("Invalid return data in get_dbseqnum\n"));
1921 talloc_free(outdata.dptr);
1925 if (seqnum != NULL) {
1926 *seqnum = *(uint64_t *)outdata.dptr;
1928 talloc_free(outdata.dptr);
1936 int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1937 TALLOC_CTX *mem_ctx, const char *name, bool persistent)
1942 uint64_t tdb_flags = 0;
1944 data.dptr = discard_const(name);
1945 data.dsize = strlen(name)+1;
1947 /* Make sure that volatile databases use jenkins hash */
1949 tdb_flags = TDB_INCOMPATIBLE_HASH;
1952 #ifdef TDB_MUTEX_LOCKING
1953 if (!persistent && ctdb->tunable.mutex_enabled == 1) {
1954 tdb_flags |= (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
1958 ret = ctdb_control(ctdb, destnode, tdb_flags,
1959 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1961 mem_ctx, &data, &res, &timeout, NULL);
1963 if (ret != 0 || res != 0) {
1971 get debug level on a node
1973 int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
1979 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
1980 ctdb, &data, &res, NULL, NULL);
1981 if (ret != 0 || res != 0) {
1984 if (data.dsize != sizeof(int32_t)) {
1985 DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
1986 (unsigned)data.dsize));
1989 *level = *(int32_t *)data.dptr;
1990 talloc_free(data.dptr);
1995 set debug level on a node
1997 int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
2003 data.dptr = (uint8_t *)&level;
2004 data.dsize = sizeof(level);
2006 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data,
2007 NULL, NULL, &res, NULL, NULL);
2008 if (ret != 0 || res != 0) {
2016 get a list of connected nodes
2018 uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
2019 struct timeval timeout,
2020 TALLOC_CTX *mem_ctx,
2021 uint32_t *num_nodes)
2023 struct ctdb_node_map *map=NULL;
2029 ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
2034 nodes = talloc_array(mem_ctx, uint32_t, map->num);
2035 if (nodes == NULL) {
2039 for (i=0;i<map->num;i++) {
2040 if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
2041 nodes[*num_nodes] = map->nodes[i].pnn;
2053 int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
2058 ret = ctdb_control(ctdb, destnode, 0,
2059 CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null,
2060 NULL, NULL, &res, NULL, NULL);
2061 if (ret != 0 || res != 0) {
2062 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
2069 attach to a specific database - client call
2071 struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
2072 struct timeval timeout,
2077 struct ctdb_db_context *ctdb_db;
2081 #ifdef TDB_MUTEX_LOCKING
2082 uint32_t mutex_enabled = 0;
2085 ctdb_db = ctdb_db_handle(ctdb, name);
2090 ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
2091 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
2093 ctdb_db->ctdb = ctdb;
2094 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
2095 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
2097 data.dptr = discard_const(name);
2098 data.dsize = strlen(name)+1;
2100 /* CTDB has switched to using jenkins hash for volatile databases.
2101 * Even if tdb_flags do not explicitly mention TDB_INCOMPATIBLE_HASH,
2105 tdb_flags |= TDB_INCOMPATIBLE_HASH;
2108 #ifdef TDB_MUTEX_LOCKING
2110 ret = ctdb_ctrl_get_tunable(ctdb, timeval_current_ofs(3,0),
2115 DEBUG(DEBUG_WARNING, ("Assuming no mutex support.\n"));
2118 if (mutex_enabled == 1) {
2119 tdb_flags |= (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
2124 /* tell ctdb daemon to attach */
2125 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags,
2126 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
2127 0, data, ctdb_db, &data, &res, NULL, NULL);
2128 if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
2129 DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
2130 talloc_free(ctdb_db);
2134 ctdb_db->db_id = *(uint32_t *)data.dptr;
2135 talloc_free(data.dptr);
2137 ret = ctdb_ctrl_getdbpath(ctdb, timeout, CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
2139 DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
2140 talloc_free(ctdb_db);
2145 tdb_flags = TDB_DEFAULT;
2147 tdb_flags = TDB_NOSYNC;
2148 #ifdef TDB_MUTEX_LOCKING
2149 if (mutex_enabled) {
2150 tdb_flags |= (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
2154 if (ctdb->valgrinding) {
2155 tdb_flags |= TDB_NOMMAP;
2157 tdb_flags |= TDB_DISALLOW_NESTING;
2159 ctdb_db->ltdb = tdb_wrap_open(ctdb_db, ctdb_db->db_path, 0, tdb_flags,
2161 if (ctdb_db->ltdb == NULL) {
2162 ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
2163 talloc_free(ctdb_db);
2167 ctdb_db->persistent = persistent;
2169 DLIST_ADD(ctdb->db_list, ctdb_db);
2171 /* add well known functions */
2172 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
2173 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
2174 ctdb_set_call(ctdb_db, ctdb_fetch_with_header_func, CTDB_FETCH_WITH_HEADER_FUNC);
2180 * detach from a specific database - client call
2182 int ctdb_detach(struct ctdb_context *ctdb, uint32_t db_id)
2188 data.dsize = sizeof(db_id);
2189 data.dptr = (uint8_t *)&db_id;
2191 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_DB_DETACH,
2192 0, data, NULL, NULL, &status, NULL, NULL);
2193 if (ret != 0 || status != 0) {
2200 setup a call for a database
2202 int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
2204 struct ctdb_registered_call *call;
2206 /* register locally */
2207 call = talloc(ctdb_db, struct ctdb_registered_call);
2211 DLIST_ADD(ctdb_db->calls, call);
2216 struct traverse_state {
2219 ctdb_traverse_func fn;
2221 bool listemptyrecords;
2225 called on each key during a ctdb_traverse
2227 static void traverse_handler(uint64_t srvid, TDB_DATA data, void *p)
2229 struct traverse_state *state = (struct traverse_state *)p;
2230 struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
2233 if (data.dsize < sizeof(uint32_t) || d->length != data.dsize) {
2234 DEBUG(DEBUG_ERR, ("Bad data size %u in traverse_handler\n",
2235 (unsigned)data.dsize));
2240 key.dsize = d->keylen;
2241 key.dptr = &d->data[0];
2242 data.dsize = d->datalen;
2243 data.dptr = &d->data[d->keylen];
2245 if (key.dsize == 0 && data.dsize == 0) {
2246 /* end of traverse */
2251 if (!state->listemptyrecords &&
2252 data.dsize == sizeof(struct ctdb_ltdb_header))
2254 /* empty records are deleted records in ctdb */
2258 if (state->fn(key, data, state->private_data) != 0) {
2266 * start a cluster wide traverse, calling the supplied fn on each record
2267 * return the number of records traversed, or -1 on error
2269 * Extendet variant with a flag to signal whether empty records should
2272 static int ctdb_traverse_ext(struct ctdb_db_context *ctdb_db,
2273 ctdb_traverse_func fn,
2274 bool withemptyrecords,
2278 struct ctdb_traverse_start_ext t;
2281 uint64_t srvid = (getpid() | 0xFLL<<60);
2282 struct traverse_state state;
2286 state.private_data = private_data;
2288 state.listemptyrecords = withemptyrecords;
2290 ret = ctdb_client_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
2292 DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
2296 t.db_id = ctdb_db->db_id;
2299 t.withemptyrecords = withemptyrecords;
2301 data.dptr = (uint8_t *)&t;
2302 data.dsize = sizeof(t);
2304 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START_EXT, 0,
2305 data, NULL, NULL, &status, NULL, NULL);
2306 if (ret != 0 || status != 0) {
2307 DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
2308 ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2312 while (!state.done) {
2313 tevent_loop_once(ctdb_db->ctdb->ev);
2316 ret = ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
2318 DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
2326 * start a cluster wide traverse, calling the supplied fn on each record
2327 * return the number of records traversed, or -1 on error
2329 * Standard version which does not list the empty records:
2330 * These are considered deleted.
2332 int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
2334 return ctdb_traverse_ext(ctdb_db, fn, false, private_data);
2337 #define ISASCII(x) (isprint(x) && !strchr("\"\\", (x)))
2339 called on each key during a catdb
2341 int ctdb_dumpdb_record(TDB_DATA key, TDB_DATA data, void *p)
2344 struct ctdb_dump_db_context *c = (struct ctdb_dump_db_context *)p;
2346 struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
2348 fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
2349 for (i=0;i<key.dsize;i++) {
2350 if (ISASCII(key.dptr[i])) {
2351 fprintf(f, "%c", key.dptr[i]);
2353 fprintf(f, "\\%02X", key.dptr[i]);
2358 fprintf(f, "dmaster: %u\n", h->dmaster);
2359 fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
2361 if (c->printlmaster && c->ctdb->vnn_map != NULL) {
2362 fprintf(f, "lmaster: %u\n", ctdb_lmaster(c->ctdb, &key));
2366 fprintf(f, "hash: 0x%08x\n", ctdb_hash(&key));
2369 if (c->printrecordflags) {
2370 fprintf(f, "flags: 0x%08x", h->flags);
2371 if (h->flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA) printf(" MIGRATED_WITH_DATA");
2372 if (h->flags & CTDB_REC_FLAG_VACUUM_MIGRATED) printf(" VACUUM_MIGRATED");
2373 if (h->flags & CTDB_REC_FLAG_AUTOMATIC) printf(" AUTOMATIC");
2374 if (h->flags & CTDB_REC_RO_HAVE_DELEGATIONS) printf(" RO_HAVE_DELEGATIONS");
2375 if (h->flags & CTDB_REC_RO_HAVE_READONLY) printf(" RO_HAVE_READONLY");
2376 if (h->flags & CTDB_REC_RO_REVOKING_READONLY) printf(" RO_REVOKING_READONLY");
2377 if (h->flags & CTDB_REC_RO_REVOKE_COMPLETE) printf(" RO_REVOKE_COMPLETE");
2381 if (c->printdatasize) {
2382 fprintf(f, "data size: %u\n", (unsigned)data.dsize);
2384 fprintf(f, "data(%u) = \"", (unsigned)(data.dsize - sizeof(*h)));
2385 for (i=sizeof(*h);i<data.dsize;i++) {
2386 if (ISASCII(data.dptr[i])) {
2387 fprintf(f, "%c", data.dptr[i]);
2389 fprintf(f, "\\%02X", data.dptr[i]);
2401 convenience function to list all keys to stdout
2403 int ctdb_dump_db(struct ctdb_db_context *ctdb_db,
2404 struct ctdb_dump_db_context *ctx)
2406 return ctdb_traverse_ext(ctdb_db, ctdb_dumpdb_record,
2407 ctx->printemptyrecords, ctx);
2411 get the pid of a ctdb daemon
2413 int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
2418 ret = ctdb_control(ctdb, destnode, 0,
2419 CTDB_CONTROL_GET_PID, 0, tdb_null,
2420 NULL, NULL, &res, &timeout, NULL);
2422 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
2433 async freeze send control
2435 struct ctdb_client_control_state *
2436 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
2438 return ctdb_control_send(ctdb, destnode, priority,
2439 CTDB_CONTROL_FREEZE, 0, tdb_null,
2440 mem_ctx, &timeout, NULL);
2444 async freeze recv control
2446 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
2451 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
2452 if ( (ret != 0) || (res != 0) ){
2453 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
2461 freeze databases of a certain priority
2463 int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2465 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2466 struct ctdb_client_control_state *state;
2469 state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
2470 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
2471 talloc_free(tmp_ctx);
2476 /* Freeze all databases */
2477 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2481 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
2482 if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
2490 thaw databases of a certain priority
2492 int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
2497 ret = ctdb_control(ctdb, destnode, priority,
2498 CTDB_CONTROL_THAW, 0, tdb_null,
2499 NULL, NULL, &res, &timeout, NULL);
2500 if (ret != 0 || res != 0) {
2501 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
2508 /* thaw all databases */
2509 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2511 return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
2515 get pnn of a node, or -1
2517 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2522 ret = ctdb_control(ctdb, destnode, 0,
2523 CTDB_CONTROL_GET_PNN, 0, tdb_null,
2524 NULL, NULL, &res, &timeout, NULL);
2526 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
2534 get the monitoring mode of a remote node
2536 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
2541 ret = ctdb_control(ctdb, destnode, 0,
2542 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
2543 NULL, NULL, &res, &timeout, NULL);
2545 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
2556 set the monitoring mode of a remote node to active
2558 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2563 ret = ctdb_control(ctdb, destnode, 0,
2564 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
2565 NULL, NULL,NULL, &timeout, NULL);
2567 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
2577 set the monitoring mode of a remote node to disable
2579 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2584 ret = ctdb_control(ctdb, destnode, 0,
2585 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
2586 NULL, NULL, NULL, &timeout, NULL);
2588 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
2600 sent to a node to make it take over an ip address
2602 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
2603 uint32_t destnode, struct ctdb_public_ip *ip)
2609 data.dsize = sizeof(*ip);
2610 data.dptr = (uint8_t *)ip;
2612 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0,
2613 data, NULL, NULL, &res, &timeout, NULL);
2614 if (ret != 0 || res != 0) {
2615 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
2624 sent to a node to make it release an ip address
2626 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
2627 uint32_t destnode, struct ctdb_public_ip *ip)
2633 data.dsize = sizeof(*ip);
2634 data.dptr = (uint8_t *)ip;
2636 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0,
2637 data, NULL, NULL, &res, &timeout, NULL);
2638 if (ret != 0 || res != 0) {
2639 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
2650 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
2651 struct timeval timeout,
2653 const char *name, uint32_t *value)
2655 struct ctdb_control_get_tunable *t;
2656 TDB_DATA data, outdata;
2660 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
2661 data.dptr = talloc_size(ctdb, data.dsize);
2662 CTDB_NO_MEMORY(ctdb, data.dptr);
2664 t = (struct ctdb_control_get_tunable *)data.dptr;
2665 t->length = strlen(name)+1;
2666 memcpy(t->name, name, t->length);
2668 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
2669 &outdata, &res, &timeout, NULL);
2670 talloc_free(data.dptr);
2671 if (ret != 0 || res != 0) {
2672 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
2673 return ret != 0 ? ret : res;
2676 if (outdata.dsize != sizeof(uint32_t)) {
2677 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
2678 talloc_free(outdata.dptr);
2682 *value = *(uint32_t *)outdata.dptr;
2683 talloc_free(outdata.dptr);
2691 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
2692 struct timeval timeout,
2694 const char *name, uint32_t value)
2696 struct ctdb_control_set_tunable *t;
2701 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
2702 data.dptr = talloc_size(ctdb, data.dsize);
2703 CTDB_NO_MEMORY(ctdb, data.dptr);
2705 t = (struct ctdb_control_set_tunable *)data.dptr;
2706 t->length = strlen(name)+1;
2707 memcpy(t->name, name, t->length);
2710 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
2711 NULL, &res, &timeout, NULL);
2712 talloc_free(data.dptr);
2713 if ((ret != 0) || (res == -1)) {
2714 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
2724 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
2725 struct timeval timeout,
2727 TALLOC_CTX *mem_ctx,
2728 const char ***list, uint32_t *count)
2733 struct ctdb_control_list_tunable *t;
2736 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
2737 mem_ctx, &outdata, &res, &timeout, NULL);
2738 if (ret != 0 || res != 0) {
2739 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
2743 t = (struct ctdb_control_list_tunable *)outdata.dptr;
2744 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
2745 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
2746 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
2747 talloc_free(outdata.dptr);
2751 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
2752 CTDB_NO_MEMORY(ctdb, p);
2754 talloc_free(outdata.dptr);
2759 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
2760 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
2761 CTDB_NO_MEMORY(ctdb, *list);
2762 (*list)[*count] = talloc_strdup(*list, s);
2763 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
2773 int ctdb_ctrl_get_public_ips_flags(struct ctdb_context *ctdb,
2774 struct timeval timeout, uint32_t destnode,
2775 TALLOC_CTX *mem_ctx,
2777 struct ctdb_all_public_ips **ips)
2783 ret = ctdb_control(ctdb, destnode, 0,
2784 CTDB_CONTROL_GET_PUBLIC_IPS, flags, tdb_null,
2785 mem_ctx, &outdata, &res, &timeout, NULL);
2786 if (ret != 0 || res != 0) {
2787 DEBUG(DEBUG_ERR,(__location__
2788 " ctdb_control for getpublicips failed ret:%d res:%d\n",
2793 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
2794 talloc_free(outdata.dptr);
2799 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
2800 struct timeval timeout, uint32_t destnode,
2801 TALLOC_CTX *mem_ctx,
2802 struct ctdb_all_public_ips **ips)
2804 return ctdb_ctrl_get_public_ips_flags(ctdb, timeout,
2809 int ctdb_ctrl_get_public_ip_info(struct ctdb_context *ctdb,
2810 struct timeval timeout, uint32_t destnode,
2811 TALLOC_CTX *mem_ctx,
2812 const ctdb_sock_addr *addr,
2813 struct ctdb_control_public_ip_info **_info)
2819 struct ctdb_control_public_ip_info *info;
2823 indata.dptr = discard_const_p(uint8_t, addr);
2824 indata.dsize = sizeof(*addr);
2826 ret = ctdb_control(ctdb, destnode, 0,
2827 CTDB_CONTROL_GET_PUBLIC_IP_INFO, 0, indata,
2828 mem_ctx, &outdata, &res, &timeout, NULL);
2829 if (ret != 0 || res != 0) {
2830 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2831 "failed ret:%d res:%d\n",
2836 len = offsetof(struct ctdb_control_public_ip_info, ifaces);
2837 if (len > outdata.dsize) {
2838 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2839 "returned invalid data with size %u > %u\n",
2840 (unsigned int)outdata.dsize,
2841 (unsigned int)len));
2842 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2846 info = (struct ctdb_control_public_ip_info *)outdata.dptr;
2847 len += info->num*sizeof(struct ctdb_control_iface_info);
2849 if (len > outdata.dsize) {
2850 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2851 "returned invalid data with size %u > %u\n",
2852 (unsigned int)outdata.dsize,
2853 (unsigned int)len));
2854 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2858 /* make sure we null terminate the returned strings */
2859 for (i=0; i < info->num; i++) {
2860 info->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2863 *_info = (struct ctdb_control_public_ip_info *)talloc_memdup(mem_ctx,
2866 talloc_free(outdata.dptr);
2867 if (*_info == NULL) {
2868 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
2869 "talloc_memdup size %u failed\n",
2870 (unsigned int)outdata.dsize));
2877 int ctdb_ctrl_get_ifaces(struct ctdb_context *ctdb,
2878 struct timeval timeout, uint32_t destnode,
2879 TALLOC_CTX *mem_ctx,
2880 struct ctdb_control_get_ifaces **_ifaces)
2885 struct ctdb_control_get_ifaces *ifaces;
2889 ret = ctdb_control(ctdb, destnode, 0,
2890 CTDB_CONTROL_GET_IFACES, 0, tdb_null,
2891 mem_ctx, &outdata, &res, &timeout, NULL);
2892 if (ret != 0 || res != 0) {
2893 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2894 "failed ret:%d res:%d\n",
2899 len = offsetof(struct ctdb_control_get_ifaces, ifaces);
2900 if (len > outdata.dsize) {
2901 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2902 "returned invalid data with size %u > %u\n",
2903 (unsigned int)outdata.dsize,
2904 (unsigned int)len));
2905 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2909 ifaces = (struct ctdb_control_get_ifaces *)outdata.dptr;
2910 len += ifaces->num*sizeof(struct ctdb_control_iface_info);
2912 if (len > outdata.dsize) {
2913 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2914 "returned invalid data with size %u > %u\n",
2915 (unsigned int)outdata.dsize,
2916 (unsigned int)len));
2917 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
2921 /* make sure we null terminate the returned strings */
2922 for (i=0; i < ifaces->num; i++) {
2923 ifaces->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
2926 *_ifaces = (struct ctdb_control_get_ifaces *)talloc_memdup(mem_ctx,
2929 talloc_free(outdata.dptr);
2930 if (*_ifaces == NULL) {
2931 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
2932 "talloc_memdup size %u failed\n",
2933 (unsigned int)outdata.dsize));
2940 int ctdb_ctrl_set_iface_link(struct ctdb_context *ctdb,
2941 struct timeval timeout, uint32_t destnode,
2942 TALLOC_CTX *mem_ctx,
2943 const struct ctdb_control_iface_info *info)
2949 indata.dptr = discard_const_p(uint8_t, info);
2950 indata.dsize = sizeof(*info);
2952 ret = ctdb_control(ctdb, destnode, 0,
2953 CTDB_CONTROL_SET_IFACE_LINK_STATE, 0, indata,
2954 mem_ctx, NULL, &res, &timeout, NULL);
2955 if (ret != 0 || res != 0) {
2956 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set iface link "
2957 "failed ret:%d res:%d\n",
2966 set/clear the permanent disabled bit on a remote node
2968 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
2969 uint32_t set, uint32_t clear)
2973 struct ctdb_node_map *nodemap=NULL;
2974 struct ctdb_node_flag_change c;
2975 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2980 /* find the recovery master */
2981 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
2983 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
2984 talloc_free(tmp_ctx);
2989 /* read the node flags from the recmaster */
2990 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
2992 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
2993 talloc_free(tmp_ctx);
2996 if (destnode >= nodemap->num) {
2997 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
2998 talloc_free(tmp_ctx);
3003 c.old_flags = nodemap->nodes[destnode].flags;
3004 c.new_flags = c.old_flags;
3006 c.new_flags &= ~clear;
3008 data.dsize = sizeof(c);
3009 data.dptr = (unsigned char *)&c;
3011 /* send the flags update to all connected nodes */
3012 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
3014 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
3016 timeout, false, data,
3019 DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
3021 talloc_free(tmp_ctx);
3025 talloc_free(tmp_ctx);
3033 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
3034 struct timeval timeout,
3036 struct ctdb_tunable *tunables)
3042 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
3043 &outdata, &res, &timeout, NULL);
3044 if (ret != 0 || res != 0) {
3045 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
3049 if (outdata.dsize != sizeof(*tunables)) {
3050 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
3051 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
3055 *tunables = *(struct ctdb_tunable *)outdata.dptr;
3056 talloc_free(outdata.dptr);
3061 add a public address to a node
3063 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
3064 struct timeval timeout,
3066 struct ctdb_control_ip_iface *pub)
3072 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
3073 data.dptr = (unsigned char *)pub;
3075 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
3076 NULL, &res, &timeout, NULL);
3077 if (ret != 0 || res != 0) {
3078 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
3086 delete a public address from a node
3088 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
3089 struct timeval timeout,
3091 struct ctdb_control_ip_iface *pub)
3097 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
3098 data.dptr = (unsigned char *)pub;
3100 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
3101 NULL, &res, &timeout, NULL);
3102 if (ret != 0 || res != 0) {
3103 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
3111 kill a tcp connection
3113 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
3114 struct timeval timeout,
3116 struct ctdb_tcp_connection *killtcp)
3122 data.dsize = sizeof(struct ctdb_tcp_connection);
3123 data.dptr = (unsigned char *)killtcp;
3125 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
3126 NULL, &res, &timeout, NULL);
3127 if (ret != 0 || res != 0) {
3128 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
3138 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
3139 struct timeval timeout,
3141 ctdb_sock_addr *addr,
3147 struct ctdb_control_gratious_arp *gratious_arp;
3148 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3151 len = strlen(ifname)+1;
3152 gratious_arp = talloc_size(tmp_ctx,
3153 offsetof(struct ctdb_control_gratious_arp, iface) + len);
3154 CTDB_NO_MEMORY(ctdb, gratious_arp);
3156 gratious_arp->addr = *addr;
3157 gratious_arp->len = len;
3158 memcpy(&gratious_arp->iface[0], ifname, len);
3161 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
3162 data.dptr = (unsigned char *)gratious_arp;
3164 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
3165 NULL, &res, &timeout, NULL);
3166 if (ret != 0 || res != 0) {
3167 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
3168 talloc_free(tmp_ctx);
3172 talloc_free(tmp_ctx);
3177 get a list of all tcp tickles that a node knows about for a particular vnn
3179 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
3180 struct timeval timeout, uint32_t destnode,
3181 TALLOC_CTX *mem_ctx,
3182 ctdb_sock_addr *addr,
3183 struct ctdb_control_tcp_tickle_list **list)
3186 TDB_DATA data, outdata;
3189 data.dptr = (uint8_t*)addr;
3190 data.dsize = sizeof(ctdb_sock_addr);
3192 ret = ctdb_control(ctdb, destnode, 0,
3193 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
3194 mem_ctx, &outdata, &status, NULL, NULL);
3195 if (ret != 0 || status != 0) {
3196 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
3200 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
3206 register a server id
3208 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
3209 struct timeval timeout,
3210 struct ctdb_server_id *id)
3216 data.dsize = sizeof(struct ctdb_server_id);
3217 data.dptr = (unsigned char *)id;
3219 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3220 CTDB_CONTROL_REGISTER_SERVER_ID,
3222 NULL, &res, &timeout, NULL);
3223 if (ret != 0 || res != 0) {
3224 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
3232 unregister a server id
3234 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
3235 struct timeval timeout,
3236 struct ctdb_server_id *id)
3242 data.dsize = sizeof(struct ctdb_server_id);
3243 data.dptr = (unsigned char *)id;
3245 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3246 CTDB_CONTROL_UNREGISTER_SERVER_ID,
3248 NULL, &res, &timeout, NULL);
3249 if (ret != 0 || res != 0) {
3250 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
3259 check if a server id exists
3261 if a server id does exist, return *status == 1, otherwise *status == 0
3263 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
3264 struct timeval timeout,
3266 struct ctdb_server_id *id,
3273 data.dsize = sizeof(struct ctdb_server_id);
3274 data.dptr = (unsigned char *)id;
3276 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
3278 NULL, &res, &timeout, NULL);
3280 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
3294 get the list of server ids that are registered on a node
3296 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
3297 TALLOC_CTX *mem_ctx,
3298 struct timeval timeout, uint32_t destnode,
3299 struct ctdb_server_id_list **svid_list)
3305 ret = ctdb_control(ctdb, destnode, 0,
3306 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
3307 mem_ctx, &outdata, &res, &timeout, NULL);
3308 if (ret != 0 || res != 0) {
3309 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
3313 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
3319 initialise the ctdb daemon for client applications
3321 NOTE: In current code the daemon does not fork. This is for testing purposes only
3322 and to simplify the code.
3324 struct ctdb_context *ctdb_init(struct tevent_context *ev)
3327 struct ctdb_context *ctdb;
3329 ctdb = talloc_zero(ev, struct ctdb_context);
3331 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
3335 /* Wrap early to exercise code. */
3336 ret = reqid_init(ctdb, INT_MAX-200, &ctdb->idr);
3338 DEBUG(DEBUG_ERR, ("reqid_init failed (%s)\n", strerror(ret)));
3343 ret = srvid_init(ctdb, &ctdb->srv);
3345 DEBUG(DEBUG_ERR, ("srvid_init failed (%s)\n", strerror(ret)));
3350 ret = ctdb_set_socketname(ctdb, CTDB_SOCKET);
3352 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
3357 ctdb->statistics.statistics_start_time = timeval_current();
3366 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
3368 ctdb->flags |= flags;
3372 setup the local socket name
3374 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
3376 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
3377 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
3382 const char *ctdb_get_socketname(struct ctdb_context *ctdb)
3384 return ctdb->daemon.name;
3388 return the pnn of this node
3390 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
3397 get the uptime of a remote node
3399 struct ctdb_client_control_state *
3400 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3402 return ctdb_control_send(ctdb, destnode, 0,
3403 CTDB_CONTROL_UPTIME, 0, tdb_null,
3404 mem_ctx, &timeout, NULL);
3407 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
3413 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3414 if (ret != 0 || res != 0) {
3415 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
3419 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
3424 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
3426 struct ctdb_client_control_state *state;
3428 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
3429 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
3433 send a control to execute the "recovered" event script on a node
3435 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3440 ret = ctdb_control(ctdb, destnode, 0,
3441 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
3442 NULL, NULL, &status, &timeout, NULL);
3443 if (ret != 0 || status != 0) {
3444 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
3452 callback for the async helpers used when sending the same control
3453 to multiple nodes in parallell.
3455 static void async_callback(struct ctdb_client_control_state *state)
3457 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
3458 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
3462 uint32_t destnode = state->c->hdr.destnode;
3465 outdata.dptr = NULL;
3467 /* one more node has responded with recmode data */
3470 /* if we failed to push the db, then return an error and let
3471 the main loop try again.
3473 if (state->state != CTDB_CONTROL_DONE) {
3474 if ( !data->dont_log_errors) {
3475 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
3478 if (state->state == CTDB_CONTROL_TIMEOUT) {
3483 if (data->fail_callback) {
3484 data->fail_callback(ctdb, destnode, res, outdata,
3485 data->callback_data);
3490 state->async.fn = NULL;
3492 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
3493 if ((ret != 0) || (res != 0)) {
3494 if ( !data->dont_log_errors) {
3495 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
3498 if (data->fail_callback) {
3499 data->fail_callback(ctdb, destnode, res, outdata,
3500 data->callback_data);
3503 if ((ret == 0) && (data->callback != NULL)) {
3504 data->callback(ctdb, destnode, res, outdata,
3505 data->callback_data);
3510 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
3512 /* set up the callback functions */
3513 state->async.fn = async_callback;
3514 state->async.private_data = data;
3516 /* one more control to wait for to complete */
3521 /* wait for up to the maximum number of seconds allowed
3522 or until all nodes we expect a response from has replied
3524 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
3526 while (data->count > 0) {
3527 tevent_loop_once(ctdb->ev);
3529 if (data->fail_count != 0) {
3530 if (!data->dont_log_errors) {
3531 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
3541 perform a simple control on the listed nodes
3542 The control cannot return data
3544 int ctdb_client_async_control(struct ctdb_context *ctdb,
3545 enum ctdb_controls opcode,
3548 struct timeval timeout,
3549 bool dont_log_errors,
3551 client_async_callback client_callback,
3552 client_async_callback fail_callback,
3553 void *callback_data)
3555 struct client_async_data *async_data;
3556 struct ctdb_client_control_state *state;
3559 async_data = talloc_zero(ctdb, struct client_async_data);
3560 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
3561 async_data->dont_log_errors = dont_log_errors;
3562 async_data->callback = client_callback;
3563 async_data->fail_callback = fail_callback;
3564 async_data->callback_data = callback_data;
3565 async_data->opcode = opcode;
3567 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
3569 /* loop over all nodes and send an async control to each of them */
3570 for (j=0; j<num_nodes; j++) {
3571 uint32_t pnn = nodes[j];
3573 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
3574 0, data, async_data, &timeout, NULL);
3575 if (state == NULL) {
3576 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
3577 talloc_free(async_data);
3581 ctdb_client_async_add(async_data, state);
3584 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
3585 talloc_free(async_data);
3589 talloc_free(async_data);
3593 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
3594 struct ctdb_vnn_map *vnn_map,
3595 TALLOC_CTX *mem_ctx,
3598 int i, j, num_nodes;
3601 for (i=num_nodes=0;i<vnn_map->size;i++) {
3602 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3608 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3609 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3611 for (i=j=0;i<vnn_map->size;i++) {
3612 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3615 nodes[j++] = vnn_map->map[i];
3621 /* Get list of nodes not including those with flags specified by mask.
3622 * If exclude_pnn is not -1 then exclude that pnn from the list.
3624 uint32_t *list_of_nodes(struct ctdb_context *ctdb,
3625 struct ctdb_node_map *node_map,
3626 TALLOC_CTX *mem_ctx,
3630 int i, j, num_nodes;
3633 for (i=num_nodes=0;i<node_map->num;i++) {
3634 if (node_map->nodes[i].flags & mask) {
3637 if (node_map->nodes[i].pnn == exclude_pnn) {
3643 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3644 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3646 for (i=j=0;i<node_map->num;i++) {
3647 if (node_map->nodes[i].flags & mask) {
3650 if (node_map->nodes[i].pnn == exclude_pnn) {
3653 nodes[j++] = node_map->nodes[i].pnn;
3659 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
3660 struct ctdb_node_map *node_map,
3661 TALLOC_CTX *mem_ctx,
3664 return list_of_nodes(ctdb, node_map, mem_ctx, NODE_FLAGS_INACTIVE,
3665 include_self ? -1 : ctdb->pnn);
3668 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
3669 struct ctdb_node_map *node_map,
3670 TALLOC_CTX *mem_ctx,
3673 return list_of_nodes(ctdb, node_map, mem_ctx, NODE_FLAGS_DISCONNECTED,
3674 include_self ? -1 : ctdb->pnn);
3678 this is used to test if a pnn lock exists and if it exists will return
3679 the number of connections that pnn has reported or -1 if that recovery
3680 daemon is not running.
3683 ctdb_read_pnn_lock(int fd, int32_t pnn)
3688 lock.l_type = F_WRLCK;
3689 lock.l_whence = SEEK_SET;
3694 if (fcntl(fd, F_GETLK, &lock) != 0) {
3695 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3699 if (lock.l_type == F_UNLCK) {
3703 if (pread(fd, &c, 1, pnn) == -1) {
3704 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3712 get capabilities of a remote node
3714 struct ctdb_client_control_state *
3715 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3717 return ctdb_control_send(ctdb, destnode, 0,
3718 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3719 mem_ctx, &timeout, NULL);
3722 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3728 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3729 if ( (ret != 0) || (res != 0) ) {
3730 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3735 *capabilities = *((uint32_t *)outdata.dptr);
3741 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3743 struct ctdb_client_control_state *state;
3744 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3747 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3748 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3749 talloc_free(tmp_ctx);
3753 static void get_capabilities_callback(struct ctdb_context *ctdb,
3754 uint32_t node_pnn, int32_t res,
3755 TDB_DATA outdata, void *callback_data)
3757 struct ctdb_node_capabilities *caps =
3758 talloc_get_type(callback_data,
3759 struct ctdb_node_capabilities);
3761 if ( (outdata.dsize != sizeof(uint32_t)) || (outdata.dptr == NULL) ) {
3762 DEBUG(DEBUG_ERR, (__location__ " Invalid length/pointer for getcap callback : %u %p\n", (unsigned)outdata.dsize, outdata.dptr));
3766 if (node_pnn >= talloc_array_length(caps)) {
3768 (__location__ " unexpected PNN %u\n", node_pnn));
3772 caps[node_pnn].retrieved = true;
3773 caps[node_pnn].capabilities = *((uint32_t *)outdata.dptr);
3776 struct ctdb_node_capabilities *
3777 ctdb_get_capabilities(struct ctdb_context *ctdb,
3778 TALLOC_CTX *mem_ctx,
3779 struct timeval timeout,
3780 struct ctdb_node_map *nodemap)
3784 struct ctdb_node_capabilities *ret;
3786 nodes = list_of_connected_nodes(ctdb, nodemap, mem_ctx, true);
3788 ret = talloc_array(mem_ctx, struct ctdb_node_capabilities,
3790 CTDB_NO_MEMORY_NULL(ctdb, ret);
3791 /* Prepopulate the expected PNNs */
3792 for (i = 0; i < talloc_array_length(ret); i++) {
3793 ret[i].retrieved = false;
3796 res = ctdb_client_async_control(ctdb, CTDB_CONTROL_GET_CAPABILITIES,
3799 get_capabilities_callback, NULL,
3803 (__location__ " Failed to read node capabilities.\n"));
3811 ctdb_get_node_capabilities(struct ctdb_node_capabilities *caps,
3814 if (pnn < talloc_array_length(caps) && caps[pnn].retrieved) {
3815 return &caps[pnn].capabilities;
3821 bool ctdb_node_has_capabilities(struct ctdb_node_capabilities *caps,
3823 uint32_t capabilities_required)
3825 uint32_t *capp = ctdb_get_node_capabilities(caps, pnn);
3826 return (capp != NULL) &&
3827 ((*capp & capabilities_required) == capabilities_required);
3838 static struct server_id server_id_fetch(struct ctdb_context *ctdb, uint32_t reqid)
3840 struct server_id id;
3844 id.vnn = ctdb_get_pnn(ctdb);
3845 id.unique_id = id.vnn;
3846 id.unique_id = (id.unique_id << 32) | reqid;
3851 /* This is basically a copy from Samba's server_id.*. However, a
3852 * dependency chain stops us from using Samba's version, so use a
3853 * renamed copy until a better solution is found. */
3854 static bool ctdb_server_id_equal(struct server_id *id1, struct server_id *id2)
3856 if (id1->pid != id2->pid) {
3860 if (id1->task_id != id2->task_id) {
3864 if (id1->vnn != id2->vnn) {
3868 if (id1->unique_id != id2->unique_id) {
3875 static bool server_id_exists(struct ctdb_context *ctdb, struct server_id *id)
3877 struct ctdb_server_id sid;
3879 uint32_t result = 0;
3881 sid.type = SERVER_TYPE_SAMBA;
3883 sid.server_id = id->pid;
3885 ret = ctdb_ctrl_check_server_id(ctdb, timeval_current_ofs(3,0),
3886 id->vnn, &sid, &result);
3888 /* If control times out, assume server_id exists. */
3906 enum g_lock_type type;
3907 struct server_id id;
3910 struct g_lock_recs {
3912 struct g_lock_rec *lock;
3915 static bool g_lock_parse(TALLOC_CTX *mem_ctx, TDB_DATA data,
3916 struct g_lock_recs **locks)
3918 struct g_lock_recs *recs;
3920 recs = talloc_zero(mem_ctx, struct g_lock_recs);
3925 if (data.dsize == 0) {
3929 if (data.dsize % sizeof(struct g_lock_rec) != 0) {
3930 DEBUG(DEBUG_ERR, (__location__ "invalid data size %lu in g_lock record\n",
3931 (unsigned long)data.dsize));
3936 recs->num = data.dsize / sizeof(struct g_lock_rec);
3937 recs->lock = talloc_memdup(mem_ctx, data.dptr, data.dsize);
3938 if (recs->lock == NULL) {
3944 if (locks != NULL) {
3952 static bool g_lock_lock(TALLOC_CTX *mem_ctx,
3953 struct ctdb_db_context *ctdb_db,
3954 const char *keyname, uint32_t reqid)
3957 struct ctdb_record_handle *h;
3958 struct g_lock_recs *locks;
3959 struct server_id id;
3960 struct timeval t_start;
3963 key.dptr = (uint8_t *)discard_const(keyname);
3964 key.dsize = strlen(keyname) + 1;
3966 t_start = timeval_current();
3969 /* Keep trying for an hour. */
3970 if (timeval_elapsed(&t_start) > 3600) {
3974 h = ctdb_fetch_lock(ctdb_db, mem_ctx, key, &data);
3979 if (!g_lock_parse(h, data, &locks)) {
3980 DEBUG(DEBUG_ERR, ("g_lock: error parsing locks\n"));
3981 talloc_free(data.dptr);
3986 talloc_free(data.dptr);
3988 id = server_id_fetch(ctdb_db->ctdb, reqid);
3991 while (i < locks->num) {
3992 if (ctdb_server_id_equal(&locks->lock[i].id, &id)) {
3993 /* Internal error */
3998 if (!server_id_exists(ctdb_db->ctdb, &locks->lock[i].id)) {
3999 if (i < locks->num-1) {
4000 locks->lock[i] = locks->lock[locks->num-1];
4006 /* This entry is locked. */
4007 DEBUG(DEBUG_INFO, ("g_lock: lock already granted for "
4008 "pid=0x%llx taskid=%x vnn=%d id=0x%llx\n",
4009 (unsigned long long)id.pid,
4011 (unsigned long long)id.unique_id));
4016 locks->lock = talloc_realloc(locks, locks->lock, struct g_lock_rec,
4018 if (locks->lock == NULL) {
4023 locks->lock[locks->num].type = G_LOCK_WRITE;
4024 locks->lock[locks->num].id = id;
4027 data.dptr = (uint8_t *)locks->lock;
4028 data.dsize = locks->num * sizeof(struct g_lock_rec);
4030 if (ctdb_record_store(h, data) != 0) {
4031 DEBUG(DEBUG_ERR, ("g_lock: failed to write transaction lock for "
4032 "pid=0x%llx taskid=%x vnn=%d id=0x%llx\n",
4033 (unsigned long long)id.pid,
4035 (unsigned long long)id.unique_id));
4040 DEBUG(DEBUG_INFO, ("g_lock: lock granted for "
4041 "pid=0x%llx taskid=%x vnn=%d id=0x%llx\n",
4042 (unsigned long long)id.pid,
4044 (unsigned long long)id.unique_id));
4050 static bool g_lock_unlock(TALLOC_CTX *mem_ctx,
4051 struct ctdb_db_context *ctdb_db,
4052 const char *keyname, uint32_t reqid)
4055 struct ctdb_record_handle *h;
4056 struct g_lock_recs *locks;
4057 struct server_id id;
4061 key.dptr = (uint8_t *)discard_const(keyname);
4062 key.dsize = strlen(keyname) + 1;
4063 h = ctdb_fetch_lock(ctdb_db, mem_ctx, key, &data);
4068 if (!g_lock_parse(h, data, &locks)) {
4069 DEBUG(DEBUG_ERR, ("g_lock: error parsing locks\n"));
4070 talloc_free(data.dptr);
4075 talloc_free(data.dptr);
4077 id = server_id_fetch(ctdb_db->ctdb, reqid);
4079 for (i=0; i<locks->num; i++) {
4080 if (ctdb_server_id_equal(&locks->lock[i].id, &id)) {
4081 if (i < locks->num-1) {
4082 locks->lock[i] = locks->lock[locks->num-1];
4091 DEBUG(DEBUG_ERR, ("g_lock: lock not found\n"));
4096 data.dptr = (uint8_t *)locks->lock;
4097 data.dsize = locks->num * sizeof(struct g_lock_rec);
4099 if (ctdb_record_store(h, data) != 0) {
4109 struct ctdb_transaction_handle {
4110 struct ctdb_db_context *ctdb_db;
4111 struct ctdb_db_context *g_lock_db;
4115 * we store reads and writes done under a transaction:
4116 * - one list stores both reads and writes (m_all)
4117 * - the other just writes (m_write)
4119 struct ctdb_marshall_buffer *m_all;
4120 struct ctdb_marshall_buffer *m_write;
4123 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
4125 g_lock_unlock(h, h->g_lock_db, h->lock_name, h->reqid);
4126 reqid_remove(h->ctdb_db->ctdb->idr, h->reqid);
4132 * start a transaction on a database
4134 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
4135 TALLOC_CTX *mem_ctx)
4137 struct ctdb_transaction_handle *h;
4138 struct ctdb_server_id id;
4140 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
4142 DEBUG(DEBUG_ERR, (__location__ " memory allocation error\n"));
4146 h->ctdb_db = ctdb_db;
4147 h->lock_name = talloc_asprintf(h, "transaction_db_0x%08x",
4148 (unsigned int)ctdb_db->db_id);
4149 if (h->lock_name == NULL) {
4150 DEBUG(DEBUG_ERR, (__location__ " talloc asprintf failed\n"));
4155 h->g_lock_db = ctdb_attach(h->ctdb_db->ctdb, timeval_current_ofs(3,0),
4156 "g_lock.tdb", false, 0);
4157 if (!h->g_lock_db) {
4158 DEBUG(DEBUG_ERR, (__location__ " unable to attach to g_lock.tdb\n"));
4163 id.type = SERVER_TYPE_SAMBA;
4164 id.pnn = ctdb_get_pnn(ctdb_db->ctdb);
4165 id.server_id = getpid();
4167 if (ctdb_ctrl_register_server_id(ctdb_db->ctdb, timeval_current_ofs(3,0),
4169 DEBUG(DEBUG_ERR, (__location__ " unable to register server id\n"));
4174 h->reqid = reqid_new(h->ctdb_db->ctdb->idr, h);
4176 if (!g_lock_lock(h, h->g_lock_db, h->lock_name, h->reqid)) {
4177 DEBUG(DEBUG_ERR, (__location__ " Error locking g_lock.tdb\n"));
4182 talloc_set_destructor(h, ctdb_transaction_destructor);
4187 * fetch a record inside a transaction
4189 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
4190 TALLOC_CTX *mem_ctx,
4191 TDB_DATA key, TDB_DATA *data)
4193 struct ctdb_ltdb_header header;
4196 ZERO_STRUCT(header);
4198 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
4199 if (ret == -1 && header.dmaster == (uint32_t)-1) {
4200 /* record doesn't exist yet */
4209 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
4210 if (h->m_all == NULL) {
4211 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
4219 * stores a record inside a transaction
4221 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
4222 TDB_DATA key, TDB_DATA data)
4224 TALLOC_CTX *tmp_ctx = talloc_new(h);
4225 struct ctdb_ltdb_header header;
4229 /* we need the header so we can update the RSN */
4230 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
4231 if (ret == -1 && header.dmaster == (uint32_t)-1) {
4232 /* the record doesn't exist - create one with us as dmaster.
4233 This is only safe because we are in a transaction and this
4234 is a persistent database */
4235 ZERO_STRUCT(header);
4236 } else if (ret != 0) {
4237 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
4238 talloc_free(tmp_ctx);
4242 if (data.dsize == olddata.dsize &&
4243 memcmp(data.dptr, olddata.dptr, data.dsize) == 0 &&
4245 /* save writing the same data */
4246 talloc_free(tmp_ctx);
4250 header.dmaster = h->ctdb_db->ctdb->pnn;
4253 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
4254 if (h->m_all == NULL) {
4255 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
4256 talloc_free(tmp_ctx);
4260 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
4261 if (h->m_write == NULL) {
4262 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
4263 talloc_free(tmp_ctx);
4267 talloc_free(tmp_ctx);
4271 static int ctdb_fetch_db_seqnum(struct ctdb_db_context *ctdb_db, uint64_t *seqnum)
4273 const char *keyname = CTDB_DB_SEQNUM_KEY;
4275 struct ctdb_ltdb_header header;
4278 key.dptr = (uint8_t *)discard_const(keyname);
4279 key.dsize = strlen(keyname) + 1;
4281 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, ctdb_db, &data);
4287 if (data.dsize == 0) {
4292 if (data.dsize != sizeof(*seqnum)) {
4293 DEBUG(DEBUG_ERR, (__location__ " Invalid data recived len=%zi\n",
4295 talloc_free(data.dptr);
4299 *seqnum = *(uint64_t *)data.dptr;
4300 talloc_free(data.dptr);
4306 static int ctdb_store_db_seqnum(struct ctdb_transaction_handle *h,
4309 const char *keyname = CTDB_DB_SEQNUM_KEY;
4312 key.dptr = (uint8_t *)discard_const(keyname);
4313 key.dsize = strlen(keyname) + 1;
4315 data.dptr = (uint8_t *)&seqnum;
4316 data.dsize = sizeof(seqnum);
4318 return ctdb_transaction_store(h, key, data);
4323 * commit a transaction
4325 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
4328 uint64_t old_seqnum, new_seqnum;
4330 struct timeval timeout;
4332 if (h->m_write == NULL) {
4333 /* no changes were made */
4338 ret = ctdb_fetch_db_seqnum(h->ctdb_db, &old_seqnum);
4340 DEBUG(DEBUG_ERR, (__location__ " failed to fetch db sequence number\n"));
4345 new_seqnum = old_seqnum + 1;
4346 ret = ctdb_store_db_seqnum(h, new_seqnum);
4348 DEBUG(DEBUG_ERR, (__location__ " failed to store db sequence number\n"));
4354 timeout = timeval_current_ofs(3,0);
4355 ret = ctdb_control(h->ctdb_db->ctdb, CTDB_CURRENT_NODE,
4357 CTDB_CONTROL_TRANS3_COMMIT, 0,
4358 ctdb_marshall_finish(h->m_write), NULL, NULL,
4359 &status, &timeout, NULL);
4360 if (ret != 0 || status != 0) {
4362 * TRANS3_COMMIT control will only fail if recovery has been
4363 * triggered. Check if the database has been updated or not.
4365 ret = ctdb_fetch_db_seqnum(h->ctdb_db, &new_seqnum);
4367 DEBUG(DEBUG_ERR, (__location__ " failed to fetch db sequence number\n"));
4371 if (new_seqnum == old_seqnum) {
4372 /* Database not yet updated, try again */
4376 if (new_seqnum != (old_seqnum + 1)) {
4377 DEBUG(DEBUG_ERR, (__location__ " new seqnum [%llu] != old seqnum [%llu] + 1\n",
4378 (long long unsigned)new_seqnum,
4379 (long long unsigned)old_seqnum));
4393 * cancel a transaction
4395 int ctdb_transaction_cancel(struct ctdb_transaction_handle *h)
4403 recovery daemon ping to main daemon
4405 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
4410 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
4411 ctdb, NULL, &res, NULL, NULL);
4412 if (ret != 0 || res != 0) {
4413 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
4420 /* When forking the main daemon and the child process needs to connect
4421 * back to the daemon as a client process, this function can be used
4422 * to change the ctdb context from daemon into client mode. The child
4423 * process must be created using ctdb_fork() and not fork() -
4424 * ctdb_fork() does some necessary housekeeping.
4426 int switch_from_server_to_client(struct ctdb_context *ctdb, const char *fmt, ...)
4431 /* Add extra information so we can identify this in the logs */
4433 debug_extra = talloc_strdup_append(talloc_vasprintf(NULL, fmt, ap), ":");
4436 /* get a new event context */
4437 ctdb->ev = tevent_context_init(ctdb);
4438 tevent_loop_allow_nesting(ctdb->ev);
4440 /* Connect to main CTDB daemon */
4441 ret = ctdb_socket_connect(ctdb);
4443 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
4447 ctdb->can_send_controls = true;
4453 get the status of running the monitor eventscripts: NULL means never run.
4455 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
4456 struct timeval timeout, uint32_t destnode,
4457 TALLOC_CTX *mem_ctx,
4458 enum ctdb_event type,
4459 struct ctdb_script_list_old **scripts)
4462 TDB_DATA outdata, indata;
4464 uint32_t uinttype = type;
4466 indata.dptr = (uint8_t *)&uinttype;
4467 indata.dsize = sizeof(uinttype);
4469 ret = ctdb_control(ctdb, destnode, 0,
4470 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, indata,
4471 mem_ctx, &outdata, &res, &timeout, NULL);
4472 if (ret != 0 || res != 0) {
4473 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
4477 if (outdata.dsize == 0) {
4480 *scripts = (struct ctdb_script_list_old *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4481 talloc_free(outdata.dptr);
4488 tell the main daemon how long it took to lock the reclock file
4490 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
4496 data.dptr = (uint8_t *)&latency;
4497 data.dsize = sizeof(latency);
4499 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
4500 ctdb, NULL, &res, NULL, NULL);
4501 if (ret != 0 || res != 0) {
4502 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
4510 get the name of the reclock file
4512 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
4513 uint32_t destnode, TALLOC_CTX *mem_ctx,
4520 ret = ctdb_control(ctdb, destnode, 0,
4521 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
4522 mem_ctx, &data, &res, &timeout, NULL);
4523 if (ret != 0 || res != 0) {
4527 if (data.dsize == 0) {
4530 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
4532 talloc_free(data.dptr);
4538 set the reclock filename for a node
4540 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
4546 if (reclock == NULL) {
4550 data.dsize = strlen(reclock) + 1;
4551 data.dptr = discard_const(reclock);
4554 ret = ctdb_control(ctdb, destnode, 0,
4555 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
4556 NULL, NULL, &res, &timeout, NULL);
4557 if (ret != 0 || res != 0) {
4558 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
4568 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4573 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
4574 ctdb, NULL, &res, &timeout, NULL);
4575 if (ret != 0 || res != 0) {
4576 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
4586 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4590 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
4591 ctdb, NULL, NULL, &timeout, NULL);
4593 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
4601 set the natgw state for a node
4603 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
4609 data.dsize = sizeof(natgwstate);
4610 data.dptr = (uint8_t *)&natgwstate;
4612 ret = ctdb_control(ctdb, destnode, 0,
4613 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
4614 NULL, NULL, &res, &timeout, NULL);
4615 if (ret != 0 || res != 0) {
4616 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
4624 set the lmaster role for a node
4626 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
4632 data.dsize = sizeof(lmasterrole);
4633 data.dptr = (uint8_t *)&lmasterrole;
4635 ret = ctdb_control(ctdb, destnode, 0,
4636 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
4637 NULL, NULL, &res, &timeout, NULL);
4638 if (ret != 0 || res != 0) {
4639 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
4647 set the recmaster role for a node
4649 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
4655 data.dsize = sizeof(recmasterrole);
4656 data.dptr = (uint8_t *)&recmasterrole;
4658 ret = ctdb_control(ctdb, destnode, 0,
4659 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
4660 NULL, NULL, &res, &timeout, NULL);
4661 if (ret != 0 || res != 0) {
4662 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
4669 /* enable an eventscript
4671 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4677 data.dsize = strlen(script) + 1;
4678 data.dptr = discard_const(script);
4680 ret = ctdb_control(ctdb, destnode, 0,
4681 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
4682 NULL, NULL, &res, &timeout, NULL);
4683 if (ret != 0 || res != 0) {
4684 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
4691 /* disable an eventscript
4693 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4699 data.dsize = strlen(script) + 1;
4700 data.dptr = discard_const(script);
4702 ret = ctdb_control(ctdb, destnode, 0,
4703 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
4704 NULL, NULL, &res, &timeout, NULL);
4705 if (ret != 0 || res != 0) {
4706 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
4714 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime)
4720 data.dsize = sizeof(*bantime);
4721 data.dptr = (uint8_t *)bantime;
4723 ret = ctdb_control(ctdb, destnode, 0,
4724 CTDB_CONTROL_SET_BAN_STATE, 0, data,
4725 NULL, NULL, &res, &timeout, NULL);
4726 if (ret != 0 || res != 0) {
4727 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4735 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime)
4740 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4742 ret = ctdb_control(ctdb, destnode, 0,
4743 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
4744 tmp_ctx, &outdata, &res, &timeout, NULL);
4745 if (ret != 0 || res != 0) {
4746 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4747 talloc_free(tmp_ctx);
4751 *bantime = (struct ctdb_ban_time *)talloc_steal(mem_ctx, outdata.dptr);
4752 talloc_free(tmp_ctx);
4758 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
4763 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4765 data.dptr = (uint8_t*)db_prio;
4766 data.dsize = sizeof(*db_prio);
4768 ret = ctdb_control(ctdb, destnode, 0,
4769 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
4770 tmp_ctx, NULL, &res, &timeout, NULL);
4771 if (ret != 0 || res != 0) {
4772 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4773 talloc_free(tmp_ctx);
4777 talloc_free(tmp_ctx);
4782 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
4787 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4789 data.dptr = (uint8_t*)&db_id;
4790 data.dsize = sizeof(db_id);
4792 ret = ctdb_control(ctdb, destnode, 0,
4793 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
4794 tmp_ctx, NULL, &res, &timeout, NULL);
4795 if (ret != 0 || res < 0) {
4796 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_db_priority failed\n"));
4797 talloc_free(tmp_ctx);
4805 talloc_free(tmp_ctx);
4810 int ctdb_ctrl_getstathistory(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_statistics_wire **stats)
4816 ret = ctdb_control(ctdb, destnode, 0,
4817 CTDB_CONTROL_GET_STAT_HISTORY, 0, tdb_null,
4818 mem_ctx, &outdata, &res, &timeout, NULL);
4819 if (ret != 0 || res != 0 || outdata.dsize == 0) {
4820 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getstathistory failed ret:%d res:%d\n", ret, res));
4824 *stats = (struct ctdb_statistics_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4825 talloc_free(outdata.dptr);
4830 struct ctdb_ltdb_header *ctdb_header_from_record_handle(struct ctdb_record_handle *h)
4840 struct ctdb_client_control_state *
4841 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)
4843 struct ctdb_client_control_state *handle;
4844 struct ctdb_marshall_buffer *m;
4845 struct ctdb_rec_data *rec;
4848 m = talloc_zero(mem_ctx, struct ctdb_marshall_buffer);
4850 DEBUG(DEBUG_ERR, ("Failed to allocate marshall buffer for update record\n"));
4854 m->db_id = ctdb_db->db_id;
4856 rec = ctdb_marshall_record(m, 0, key, header, data);
4858 DEBUG(DEBUG_ERR,("Failed to marshall record for update record\n"));
4862 m = talloc_realloc_size(mem_ctx, m, rec->length + offsetof(struct ctdb_marshall_buffer, data));
4864 DEBUG(DEBUG_CRIT,(__location__ " Failed to expand recdata\n"));
4869 memcpy((uint8_t *)m + offsetof(struct ctdb_marshall_buffer, data), rec, rec->length);
4872 outdata.dptr = (uint8_t *)m;
4873 outdata.dsize = talloc_get_size(m);
4875 handle = ctdb_control_send(ctdb, destnode, 0,
4876 CTDB_CONTROL_UPDATE_RECORD, 0, outdata,
4877 mem_ctx, &timeout, NULL);
4882 int ctdb_ctrl_updaterecord_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4887 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
4888 if ( (ret != 0) || (res != 0) ){
4889 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_update_record_recv failed\n"));
4897 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)
4899 struct ctdb_client_control_state *state;
4901 state = ctdb_ctrl_updaterecord_send(ctdb, mem_ctx, timeout, destnode, ctdb_db, key, header, data);
4902 return ctdb_ctrl_updaterecord_recv(ctdb, state);
4911 set a database to be readonly
4913 struct ctdb_client_control_state *
4914 ctdb_ctrl_set_db_readonly_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4918 data.dptr = (uint8_t *)&dbid;
4919 data.dsize = sizeof(dbid);
4921 return ctdb_control_send(ctdb, destnode, 0,
4922 CTDB_CONTROL_SET_DB_READONLY, 0, data,
4926 int ctdb_ctrl_set_db_readonly_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4931 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4932 if (ret != 0 || res != 0) {
4933 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_readonly_recv failed ret:%d res:%d\n", ret, res));
4940 int ctdb_ctrl_set_db_readonly(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4942 struct ctdb_client_control_state *state;
4944 state = ctdb_ctrl_set_db_readonly_send(ctdb, destnode, dbid);
4945 return ctdb_ctrl_set_db_readonly_recv(ctdb, state);
4949 set a database to be sticky
4951 struct ctdb_client_control_state *
4952 ctdb_ctrl_set_db_sticky_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4956 data.dptr = (uint8_t *)&dbid;
4957 data.dsize = sizeof(dbid);
4959 return ctdb_control_send(ctdb, destnode, 0,
4960 CTDB_CONTROL_SET_DB_STICKY, 0, data,
4964 int ctdb_ctrl_set_db_sticky_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4969 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4970 if (ret != 0 || res != 0) {
4971 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_sticky_recv failed ret:%d res:%d\n", ret, res));
4978 int ctdb_ctrl_set_db_sticky(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4980 struct ctdb_client_control_state *state;
4982 state = ctdb_ctrl_set_db_sticky_send(ctdb, destnode, dbid);
4983 return ctdb_ctrl_set_db_sticky_recv(ctdb, state);