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_private.h"
39 #include "ctdb_client.h"
41 #include "common/reqid.h"
42 #include "common/system.h"
43 #include "common/common.h"
44 #include "common/logging.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 don't 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_old **dbstat)
1298 TDB_DATA indata, outdata;
1300 struct ctdb_db_statistics_old *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_old, 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_old);
1323 talloc_free(outdata.dptr);
1324 CTDB_NO_MEMORY(ctdb, s);
1327 wire = (struct ctdb_db_statistics_old *)outdata.dptr;
1328 memcpy(s, wire, offsetof(struct ctdb_db_statistics_old, 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_old **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_old *)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_old **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_old *)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_old **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_old *)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_pulldb *pull;
1672 struct ctdb_client_control_state *state;
1674 pull = talloc(mem_ctx, struct ctdb_pulldb);
1675 CTDB_NO_MEMORY_NULL(ctdb, pull);
1678 pull->lmaster = lmaster;
1680 indata.dsize = sizeof(struct ctdb_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_old *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_old *d = (struct ctdb_rec_data_old *)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_tunable_old *t;
2701 data.dsize = offsetof(struct ctdb_tunable_old, name) + strlen(name) + 1;
2702 data.dptr = talloc_size(ctdb, data.dsize);
2703 CTDB_NO_MEMORY(ctdb, data.dptr);
2705 t = (struct ctdb_tunable_old *)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_public_ip_list_old **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_public_ip_list_old *)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_public_ip_list_old **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_public_ip_info_old **_info)
2819 struct ctdb_public_ip_info_old *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_public_ip_info_old, 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_public_ip_info_old *)outdata.dptr;
2847 len += info->num*sizeof(struct ctdb_iface);
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_public_ip_info_old *)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_iface_list_old **_ifaces)
2885 struct ctdb_iface_list_old *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_iface_list_old, 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_iface_list_old *)outdata.dptr;
2910 len += ifaces->num*sizeof(struct ctdb_iface);
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_iface_list_old *)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_iface *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_old *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_list *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_list *)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, uint32_t destnode,
3065 struct ctdb_addr_info_old *pub)
3071 data.dsize = offsetof(struct ctdb_addr_info_old, iface) + pub->len;
3072 data.dptr = (unsigned char *)pub;
3074 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
3075 NULL, &res, &timeout, NULL);
3076 if (ret != 0 || res != 0) {
3077 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
3085 delete a public address from a node
3087 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
3088 struct timeval timeout, uint32_t destnode,
3089 struct ctdb_addr_info_old *pub)
3095 data.dsize = offsetof(struct ctdb_addr_info_old, iface) + pub->len;
3096 data.dptr = (unsigned char *)pub;
3098 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
3099 NULL, &res, &timeout, NULL);
3100 if (ret != 0 || res != 0) {
3101 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
3109 kill a tcp connection
3111 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
3112 struct timeval timeout,
3114 struct ctdb_connection *killtcp)
3120 data.dsize = sizeof(struct ctdb_connection);
3121 data.dptr = (unsigned char *)killtcp;
3123 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
3124 NULL, &res, &timeout, NULL);
3125 if (ret != 0 || res != 0) {
3126 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
3136 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
3137 struct timeval timeout, uint32_t destnode,
3138 ctdb_sock_addr *addr, const char *ifname)
3143 struct ctdb_addr_info_old *gratious_arp;
3144 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
3147 len = strlen(ifname)+1;
3148 gratious_arp = talloc_size(tmp_ctx,
3149 offsetof(struct ctdb_addr_info_old, iface) + len);
3150 CTDB_NO_MEMORY(ctdb, gratious_arp);
3152 gratious_arp->addr = *addr;
3153 gratious_arp->len = len;
3154 memcpy(&gratious_arp->iface[0], ifname, len);
3157 data.dsize = offsetof(struct ctdb_addr_info_old, iface) + len;
3158 data.dptr = (unsigned char *)gratious_arp;
3160 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATUITOUS_ARP, 0, data, NULL,
3161 NULL, &res, &timeout, NULL);
3162 if (ret != 0 || res != 0) {
3163 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
3164 talloc_free(tmp_ctx);
3168 talloc_free(tmp_ctx);
3173 get a list of all tcp tickles that a node knows about for a particular vnn
3175 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
3176 struct timeval timeout, uint32_t destnode,
3177 TALLOC_CTX *mem_ctx,
3178 ctdb_sock_addr *addr,
3179 struct ctdb_tickle_list_old **list)
3182 TDB_DATA data, outdata;
3185 data.dptr = (uint8_t*)addr;
3186 data.dsize = sizeof(ctdb_sock_addr);
3188 ret = ctdb_control(ctdb, destnode, 0,
3189 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
3190 mem_ctx, &outdata, &status, NULL, NULL);
3191 if (ret != 0 || status != 0) {
3192 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
3196 *list = (struct ctdb_tickle_list_old *)outdata.dptr;
3202 register a server id
3204 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
3205 struct timeval timeout,
3206 struct ctdb_client_id *id)
3212 data.dsize = sizeof(struct ctdb_client_id);
3213 data.dptr = (unsigned char *)id;
3215 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3216 CTDB_CONTROL_REGISTER_SERVER_ID,
3218 NULL, &res, &timeout, NULL);
3219 if (ret != 0 || res != 0) {
3220 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
3228 unregister a server id
3230 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
3231 struct timeval timeout,
3232 struct ctdb_client_id *id)
3238 data.dsize = sizeof(struct ctdb_client_id);
3239 data.dptr = (unsigned char *)id;
3241 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
3242 CTDB_CONTROL_UNREGISTER_SERVER_ID,
3244 NULL, &res, &timeout, NULL);
3245 if (ret != 0 || res != 0) {
3246 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
3255 check if a server id exists
3257 if a server id does exist, return *status == 1, otherwise *status == 0
3259 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
3260 struct timeval timeout, uint32_t destnode,
3261 struct ctdb_client_id *id, uint32_t *status)
3267 data.dsize = sizeof(struct ctdb_client_id);
3268 data.dptr = (unsigned char *)id;
3270 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
3272 NULL, &res, &timeout, NULL);
3274 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
3288 get the list of server ids that are registered on a node
3290 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
3291 TALLOC_CTX *mem_ctx,
3292 struct timeval timeout, uint32_t destnode,
3293 struct ctdb_client_id_list_old **svid_list)
3299 ret = ctdb_control(ctdb, destnode, 0,
3300 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
3301 mem_ctx, &outdata, &res, &timeout, NULL);
3302 if (ret != 0 || res != 0) {
3303 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
3307 *svid_list = (struct ctdb_client_id_list_old *)talloc_steal(mem_ctx, outdata.dptr);
3313 initialise the ctdb daemon for client applications
3315 NOTE: In current code the daemon does not fork. This is for testing purposes only
3316 and to simplify the code.
3318 struct ctdb_context *ctdb_init(struct tevent_context *ev)
3321 struct ctdb_context *ctdb;
3323 ctdb = talloc_zero(ev, struct ctdb_context);
3325 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
3329 /* Wrap early to exercise code. */
3330 ret = reqid_init(ctdb, INT_MAX-200, &ctdb->idr);
3332 DEBUG(DEBUG_ERR, ("reqid_init failed (%s)\n", strerror(ret)));
3337 ret = srvid_init(ctdb, &ctdb->srv);
3339 DEBUG(DEBUG_ERR, ("srvid_init failed (%s)\n", strerror(ret)));
3344 ret = ctdb_set_socketname(ctdb, CTDB_SOCKET);
3346 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
3351 ctdb->statistics.statistics_start_time = timeval_current();
3360 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
3362 ctdb->flags |= flags;
3366 setup the local socket name
3368 int ctdb_set_socketname(struct ctdb_context *ctdb, const char *socketname)
3370 ctdb->daemon.name = talloc_strdup(ctdb, socketname);
3371 CTDB_NO_MEMORY(ctdb, ctdb->daemon.name);
3376 const char *ctdb_get_socketname(struct ctdb_context *ctdb)
3378 return ctdb->daemon.name;
3382 return the pnn of this node
3384 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
3391 get the uptime of a remote node
3393 struct ctdb_client_control_state *
3394 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3396 return ctdb_control_send(ctdb, destnode, 0,
3397 CTDB_CONTROL_UPTIME, 0, tdb_null,
3398 mem_ctx, &timeout, NULL);
3401 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
3407 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3408 if (ret != 0 || res != 0) {
3409 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
3413 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
3418 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
3420 struct ctdb_client_control_state *state;
3422 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
3423 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
3427 send a control to execute the "recovered" event script on a node
3429 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3434 ret = ctdb_control(ctdb, destnode, 0,
3435 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
3436 NULL, NULL, &status, &timeout, NULL);
3437 if (ret != 0 || status != 0) {
3438 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
3446 callback for the async helpers used when sending the same control
3447 to multiple nodes in parallell.
3449 static void async_callback(struct ctdb_client_control_state *state)
3451 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
3452 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
3456 uint32_t destnode = state->c->hdr.destnode;
3459 outdata.dptr = NULL;
3461 /* one more node has responded with recmode data */
3464 /* if we failed to push the db, then return an error and let
3465 the main loop try again.
3467 if (state->state != CTDB_CONTROL_DONE) {
3468 if ( !data->dont_log_errors) {
3469 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
3472 if (state->state == CTDB_CONTROL_TIMEOUT) {
3477 if (data->fail_callback) {
3478 data->fail_callback(ctdb, destnode, res, outdata,
3479 data->callback_data);
3484 state->async.fn = NULL;
3486 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
3487 if ((ret != 0) || (res != 0)) {
3488 if ( !data->dont_log_errors) {
3489 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
3492 if (data->fail_callback) {
3493 data->fail_callback(ctdb, destnode, res, outdata,
3494 data->callback_data);
3497 if ((ret == 0) && (data->callback != NULL)) {
3498 data->callback(ctdb, destnode, res, outdata,
3499 data->callback_data);
3504 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
3506 /* set up the callback functions */
3507 state->async.fn = async_callback;
3508 state->async.private_data = data;
3510 /* one more control to wait for to complete */
3515 /* wait for up to the maximum number of seconds allowed
3516 or until all nodes we expect a response from has replied
3518 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
3520 while (data->count > 0) {
3521 tevent_loop_once(ctdb->ev);
3523 if (data->fail_count != 0) {
3524 if (!data->dont_log_errors) {
3525 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
3535 perform a simple control on the listed nodes
3536 The control cannot return data
3538 int ctdb_client_async_control(struct ctdb_context *ctdb,
3539 enum ctdb_controls opcode,
3542 struct timeval timeout,
3543 bool dont_log_errors,
3545 client_async_callback client_callback,
3546 client_async_callback fail_callback,
3547 void *callback_data)
3549 struct client_async_data *async_data;
3550 struct ctdb_client_control_state *state;
3553 async_data = talloc_zero(ctdb, struct client_async_data);
3554 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
3555 async_data->dont_log_errors = dont_log_errors;
3556 async_data->callback = client_callback;
3557 async_data->fail_callback = fail_callback;
3558 async_data->callback_data = callback_data;
3559 async_data->opcode = opcode;
3561 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
3563 /* loop over all nodes and send an async control to each of them */
3564 for (j=0; j<num_nodes; j++) {
3565 uint32_t pnn = nodes[j];
3567 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
3568 0, data, async_data, &timeout, NULL);
3569 if (state == NULL) {
3570 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
3571 talloc_free(async_data);
3575 ctdb_client_async_add(async_data, state);
3578 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
3579 talloc_free(async_data);
3583 talloc_free(async_data);
3587 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
3588 struct ctdb_vnn_map *vnn_map,
3589 TALLOC_CTX *mem_ctx,
3592 int i, j, num_nodes;
3595 for (i=num_nodes=0;i<vnn_map->size;i++) {
3596 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3602 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3603 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3605 for (i=j=0;i<vnn_map->size;i++) {
3606 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
3609 nodes[j++] = vnn_map->map[i];
3615 /* Get list of nodes not including those with flags specified by mask.
3616 * If exclude_pnn is not -1 then exclude that pnn from the list.
3618 uint32_t *list_of_nodes(struct ctdb_context *ctdb,
3619 struct ctdb_node_map_old *node_map,
3620 TALLOC_CTX *mem_ctx,
3624 int i, j, num_nodes;
3627 for (i=num_nodes=0;i<node_map->num;i++) {
3628 if (node_map->nodes[i].flags & mask) {
3631 if (node_map->nodes[i].pnn == exclude_pnn) {
3637 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
3638 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
3640 for (i=j=0;i<node_map->num;i++) {
3641 if (node_map->nodes[i].flags & mask) {
3644 if (node_map->nodes[i].pnn == exclude_pnn) {
3647 nodes[j++] = node_map->nodes[i].pnn;
3653 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
3654 struct ctdb_node_map_old *node_map,
3655 TALLOC_CTX *mem_ctx,
3658 return list_of_nodes(ctdb, node_map, mem_ctx, NODE_FLAGS_INACTIVE,
3659 include_self ? -1 : ctdb->pnn);
3662 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
3663 struct ctdb_node_map_old *node_map,
3664 TALLOC_CTX *mem_ctx,
3667 return list_of_nodes(ctdb, node_map, mem_ctx, NODE_FLAGS_DISCONNECTED,
3668 include_self ? -1 : ctdb->pnn);
3672 this is used to test if a pnn lock exists and if it exists will return
3673 the number of connections that pnn has reported or -1 if that recovery
3674 daemon is not running.
3677 ctdb_read_pnn_lock(int fd, int32_t pnn)
3682 lock.l_type = F_WRLCK;
3683 lock.l_whence = SEEK_SET;
3688 if (fcntl(fd, F_GETLK, &lock) != 0) {
3689 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
3693 if (lock.l_type == F_UNLCK) {
3697 if (pread(fd, &c, 1, pnn) == -1) {
3698 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
3706 get capabilities of a remote node
3708 struct ctdb_client_control_state *
3709 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
3711 return ctdb_control_send(ctdb, destnode, 0,
3712 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
3713 mem_ctx, &timeout, NULL);
3716 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
3722 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
3723 if ( (ret != 0) || (res != 0) ) {
3724 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
3729 *capabilities = *((uint32_t *)outdata.dptr);
3735 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
3737 struct ctdb_client_control_state *state;
3738 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3741 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
3742 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
3743 talloc_free(tmp_ctx);
3747 static void get_capabilities_callback(struct ctdb_context *ctdb,
3748 uint32_t node_pnn, int32_t res,
3749 TDB_DATA outdata, void *callback_data)
3751 struct ctdb_node_capabilities *caps =
3752 talloc_get_type(callback_data,
3753 struct ctdb_node_capabilities);
3755 if ( (outdata.dsize != sizeof(uint32_t)) || (outdata.dptr == NULL) ) {
3756 DEBUG(DEBUG_ERR, (__location__ " Invalid length/pointer for getcap callback : %u %p\n", (unsigned)outdata.dsize, outdata.dptr));
3760 if (node_pnn >= talloc_array_length(caps)) {
3762 (__location__ " unexpected PNN %u\n", node_pnn));
3766 caps[node_pnn].retrieved = true;
3767 caps[node_pnn].capabilities = *((uint32_t *)outdata.dptr);
3770 struct ctdb_node_capabilities *
3771 ctdb_get_capabilities(struct ctdb_context *ctdb,
3772 TALLOC_CTX *mem_ctx,
3773 struct timeval timeout,
3774 struct ctdb_node_map_old *nodemap)
3778 struct ctdb_node_capabilities *ret;
3780 nodes = list_of_active_nodes(ctdb, nodemap, mem_ctx, true);
3782 ret = talloc_array(mem_ctx, struct ctdb_node_capabilities,
3784 CTDB_NO_MEMORY_NULL(ctdb, ret);
3785 /* Prepopulate the expected PNNs */
3786 for (i = 0; i < talloc_array_length(ret); i++) {
3787 ret[i].retrieved = false;
3790 res = ctdb_client_async_control(ctdb, CTDB_CONTROL_GET_CAPABILITIES,
3793 get_capabilities_callback, NULL,
3797 (__location__ " Failed to read node capabilities.\n"));
3805 ctdb_get_node_capabilities(struct ctdb_node_capabilities *caps,
3808 if (pnn < talloc_array_length(caps) && caps[pnn].retrieved) {
3809 return &caps[pnn].capabilities;
3815 bool ctdb_node_has_capabilities(struct ctdb_node_capabilities *caps,
3817 uint32_t capabilities_required)
3819 uint32_t *capp = ctdb_get_node_capabilities(caps, pnn);
3820 return (capp != NULL) &&
3821 ((*capp & capabilities_required) == capabilities_required);
3825 static struct ctdb_server_id server_id_fetch(struct ctdb_context *ctdb, uint32_t reqid)
3827 struct ctdb_server_id id;
3831 id.vnn = ctdb_get_pnn(ctdb);
3832 id.unique_id = id.vnn;
3833 id.unique_id = (id.unique_id << 32) | reqid;
3838 /* This is basically a copy from Samba's server_id.*. However, a
3839 * dependency chain stops us from using Samba's version, so use a
3840 * renamed copy until a better solution is found. */
3841 static bool ctdb_server_id_equal(struct ctdb_server_id *id1, struct ctdb_server_id *id2)
3843 if (id1->pid != id2->pid) {
3847 if (id1->task_id != id2->task_id) {
3851 if (id1->vnn != id2->vnn) {
3855 if (id1->unique_id != id2->unique_id) {
3862 static bool server_id_exists(struct ctdb_context *ctdb, struct ctdb_server_id *id)
3864 struct ctdb_client_id sid;
3866 uint32_t result = 0;
3868 sid.type = SERVER_TYPE_SAMBA;
3870 sid.server_id = id->pid;
3872 ret = ctdb_ctrl_check_server_id(ctdb, timeval_current_ofs(3,0),
3873 id->vnn, &sid, &result);
3875 /* If control times out, assume server_id exists. */
3886 static bool g_lock_parse(TALLOC_CTX *mem_ctx, TDB_DATA data,
3887 struct ctdb_g_lock_list **locks)
3889 struct ctdb_g_lock_list *recs;
3891 recs = talloc_zero(mem_ctx, struct ctdb_g_lock_list);
3896 if (data.dsize == 0) {
3900 if (data.dsize % sizeof(struct ctdb_g_lock) != 0) {
3901 DEBUG(DEBUG_ERR, (__location__ "invalid data size %lu in g_lock record\n",
3902 (unsigned long)data.dsize));
3907 recs->num = data.dsize / sizeof(struct ctdb_g_lock);
3908 recs->lock = talloc_memdup(mem_ctx, data.dptr, data.dsize);
3909 if (recs->lock == NULL) {
3915 if (locks != NULL) {
3923 static bool g_lock_lock(TALLOC_CTX *mem_ctx,
3924 struct ctdb_db_context *ctdb_db,
3925 const char *keyname, uint32_t reqid)
3928 struct ctdb_record_handle *h;
3929 struct ctdb_g_lock_list *locks;
3930 struct ctdb_server_id id;
3931 struct timeval t_start;
3934 key.dptr = (uint8_t *)discard_const(keyname);
3935 key.dsize = strlen(keyname) + 1;
3937 t_start = timeval_current();
3940 /* Keep trying for an hour. */
3941 if (timeval_elapsed(&t_start) > 3600) {
3945 h = ctdb_fetch_lock(ctdb_db, mem_ctx, key, &data);
3950 if (!g_lock_parse(h, data, &locks)) {
3951 DEBUG(DEBUG_ERR, ("g_lock: error parsing locks\n"));
3952 talloc_free(data.dptr);
3957 talloc_free(data.dptr);
3959 id = server_id_fetch(ctdb_db->ctdb, reqid);
3962 while (i < locks->num) {
3963 if (ctdb_server_id_equal(&locks->lock[i].sid, &id)) {
3964 /* Internal error */
3969 if (!server_id_exists(ctdb_db->ctdb, &locks->lock[i].sid)) {
3970 if (i < locks->num-1) {
3971 locks->lock[i] = locks->lock[locks->num-1];
3977 /* This entry is locked. */
3978 DEBUG(DEBUG_INFO, ("g_lock: lock already granted for "
3979 "pid=0x%llx taskid=%x vnn=%d id=0x%llx\n",
3980 (unsigned long long)id.pid,
3982 (unsigned long long)id.unique_id));
3987 locks->lock = talloc_realloc(locks, locks->lock, struct ctdb_g_lock,
3989 if (locks->lock == NULL) {
3994 locks->lock[locks->num].type = CTDB_G_LOCK_WRITE;
3995 locks->lock[locks->num].sid = id;
3998 data.dptr = (uint8_t *)locks->lock;
3999 data.dsize = locks->num * sizeof(struct ctdb_g_lock);
4001 if (ctdb_record_store(h, data) != 0) {
4002 DEBUG(DEBUG_ERR, ("g_lock: failed to write transaction lock for "
4003 "pid=0x%llx taskid=%x vnn=%d id=0x%llx\n",
4004 (unsigned long long)id.pid,
4006 (unsigned long long)id.unique_id));
4011 DEBUG(DEBUG_INFO, ("g_lock: lock granted for "
4012 "pid=0x%llx taskid=%x vnn=%d id=0x%llx\n",
4013 (unsigned long long)id.pid,
4015 (unsigned long long)id.unique_id));
4021 static bool g_lock_unlock(TALLOC_CTX *mem_ctx,
4022 struct ctdb_db_context *ctdb_db,
4023 const char *keyname, uint32_t reqid)
4026 struct ctdb_record_handle *h;
4027 struct ctdb_g_lock_list *locks;
4028 struct ctdb_server_id id;
4032 key.dptr = (uint8_t *)discard_const(keyname);
4033 key.dsize = strlen(keyname) + 1;
4034 h = ctdb_fetch_lock(ctdb_db, mem_ctx, key, &data);
4039 if (!g_lock_parse(h, data, &locks)) {
4040 DEBUG(DEBUG_ERR, ("g_lock: error parsing locks\n"));
4041 talloc_free(data.dptr);
4046 talloc_free(data.dptr);
4048 id = server_id_fetch(ctdb_db->ctdb, reqid);
4050 for (i=0; i<locks->num; i++) {
4051 if (ctdb_server_id_equal(&locks->lock[i].sid, &id)) {
4052 if (i < locks->num-1) {
4053 locks->lock[i] = locks->lock[locks->num-1];
4062 DEBUG(DEBUG_ERR, ("g_lock: lock not found\n"));
4067 data.dptr = (uint8_t *)locks->lock;
4068 data.dsize = locks->num * sizeof(struct ctdb_g_lock);
4070 if (ctdb_record_store(h, data) != 0) {
4080 struct ctdb_transaction_handle {
4081 struct ctdb_db_context *ctdb_db;
4082 struct ctdb_db_context *g_lock_db;
4086 * we store reads and writes done under a transaction:
4087 * - one list stores both reads and writes (m_all)
4088 * - the other just writes (m_write)
4090 struct ctdb_marshall_buffer *m_all;
4091 struct ctdb_marshall_buffer *m_write;
4094 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
4096 g_lock_unlock(h, h->g_lock_db, h->lock_name, h->reqid);
4097 reqid_remove(h->ctdb_db->ctdb->idr, h->reqid);
4103 * start a transaction on a database
4105 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
4106 TALLOC_CTX *mem_ctx)
4108 struct ctdb_transaction_handle *h;
4109 struct ctdb_client_id id;
4111 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
4113 DEBUG(DEBUG_ERR, (__location__ " memory allocation error\n"));
4117 h->ctdb_db = ctdb_db;
4118 h->lock_name = talloc_asprintf(h, "transaction_db_0x%08x",
4119 (unsigned int)ctdb_db->db_id);
4120 if (h->lock_name == NULL) {
4121 DEBUG(DEBUG_ERR, (__location__ " talloc asprintf failed\n"));
4126 h->g_lock_db = ctdb_attach(h->ctdb_db->ctdb, timeval_current_ofs(3,0),
4127 "g_lock.tdb", false, 0);
4128 if (!h->g_lock_db) {
4129 DEBUG(DEBUG_ERR, (__location__ " unable to attach to g_lock.tdb\n"));
4134 id.type = SERVER_TYPE_SAMBA;
4135 id.pnn = ctdb_get_pnn(ctdb_db->ctdb);
4136 id.server_id = getpid();
4138 if (ctdb_ctrl_register_server_id(ctdb_db->ctdb, timeval_current_ofs(3,0),
4140 DEBUG(DEBUG_ERR, (__location__ " unable to register server id\n"));
4145 h->reqid = reqid_new(h->ctdb_db->ctdb->idr, h);
4147 if (!g_lock_lock(h, h->g_lock_db, h->lock_name, h->reqid)) {
4148 DEBUG(DEBUG_ERR, (__location__ " Error locking g_lock.tdb\n"));
4153 talloc_set_destructor(h, ctdb_transaction_destructor);
4158 * fetch a record inside a transaction
4160 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
4161 TALLOC_CTX *mem_ctx,
4162 TDB_DATA key, TDB_DATA *data)
4164 struct ctdb_ltdb_header header;
4167 ZERO_STRUCT(header);
4169 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
4170 if (ret == -1 && header.dmaster == (uint32_t)-1) {
4171 /* record doesn't exist yet */
4180 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
4181 if (h->m_all == NULL) {
4182 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
4190 * stores a record inside a transaction
4192 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
4193 TDB_DATA key, TDB_DATA data)
4195 TALLOC_CTX *tmp_ctx = talloc_new(h);
4196 struct ctdb_ltdb_header header;
4200 /* we need the header so we can update the RSN */
4201 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
4202 if (ret == -1 && header.dmaster == (uint32_t)-1) {
4203 /* the record doesn't exist - create one with us as dmaster.
4204 This is only safe because we are in a transaction and this
4205 is a persistent database */
4206 ZERO_STRUCT(header);
4207 } else if (ret != 0) {
4208 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
4209 talloc_free(tmp_ctx);
4213 if (data.dsize == olddata.dsize &&
4214 memcmp(data.dptr, olddata.dptr, data.dsize) == 0 &&
4216 /* save writing the same data */
4217 talloc_free(tmp_ctx);
4221 header.dmaster = h->ctdb_db->ctdb->pnn;
4224 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
4225 if (h->m_all == NULL) {
4226 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
4227 talloc_free(tmp_ctx);
4231 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
4232 if (h->m_write == NULL) {
4233 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
4234 talloc_free(tmp_ctx);
4238 talloc_free(tmp_ctx);
4242 static int ctdb_fetch_db_seqnum(struct ctdb_db_context *ctdb_db, uint64_t *seqnum)
4244 const char *keyname = CTDB_DB_SEQNUM_KEY;
4246 struct ctdb_ltdb_header header;
4249 key.dptr = (uint8_t *)discard_const(keyname);
4250 key.dsize = strlen(keyname) + 1;
4252 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, ctdb_db, &data);
4258 if (data.dsize == 0) {
4263 if (data.dsize != sizeof(*seqnum)) {
4264 DEBUG(DEBUG_ERR, (__location__ " Invalid data recived len=%zi\n",
4266 talloc_free(data.dptr);
4270 *seqnum = *(uint64_t *)data.dptr;
4271 talloc_free(data.dptr);
4277 static int ctdb_store_db_seqnum(struct ctdb_transaction_handle *h,
4280 const char *keyname = CTDB_DB_SEQNUM_KEY;
4283 key.dptr = (uint8_t *)discard_const(keyname);
4284 key.dsize = strlen(keyname) + 1;
4286 data.dptr = (uint8_t *)&seqnum;
4287 data.dsize = sizeof(seqnum);
4289 return ctdb_transaction_store(h, key, data);
4294 * commit a transaction
4296 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
4299 uint64_t old_seqnum, new_seqnum;
4301 struct timeval timeout;
4303 if (h->m_write == NULL) {
4304 /* no changes were made */
4309 ret = ctdb_fetch_db_seqnum(h->ctdb_db, &old_seqnum);
4311 DEBUG(DEBUG_ERR, (__location__ " failed to fetch db sequence number\n"));
4316 new_seqnum = old_seqnum + 1;
4317 ret = ctdb_store_db_seqnum(h, new_seqnum);
4319 DEBUG(DEBUG_ERR, (__location__ " failed to store db sequence number\n"));
4325 timeout = timeval_current_ofs(3,0);
4326 ret = ctdb_control(h->ctdb_db->ctdb, CTDB_CURRENT_NODE,
4328 CTDB_CONTROL_TRANS3_COMMIT, 0,
4329 ctdb_marshall_finish(h->m_write), NULL, NULL,
4330 &status, &timeout, NULL);
4331 if (ret != 0 || status != 0) {
4333 * TRANS3_COMMIT control will only fail if recovery has been
4334 * triggered. Check if the database has been updated or not.
4336 ret = ctdb_fetch_db_seqnum(h->ctdb_db, &new_seqnum);
4338 DEBUG(DEBUG_ERR, (__location__ " failed to fetch db sequence number\n"));
4342 if (new_seqnum == old_seqnum) {
4343 /* Database not yet updated, try again */
4347 if (new_seqnum != (old_seqnum + 1)) {
4348 DEBUG(DEBUG_ERR, (__location__ " new seqnum [%llu] != old seqnum [%llu] + 1\n",
4349 (long long unsigned)new_seqnum,
4350 (long long unsigned)old_seqnum));
4364 * cancel a transaction
4366 int ctdb_transaction_cancel(struct ctdb_transaction_handle *h)
4374 recovery daemon ping to main daemon
4376 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
4381 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
4382 ctdb, NULL, &res, NULL, NULL);
4383 if (ret != 0 || res != 0) {
4384 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
4392 get the status of running the monitor eventscripts: NULL means never run.
4394 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
4395 struct timeval timeout, uint32_t destnode,
4396 TALLOC_CTX *mem_ctx,
4397 enum ctdb_event type,
4398 struct ctdb_script_list_old **scripts)
4401 TDB_DATA outdata, indata;
4403 uint32_t uinttype = type;
4405 indata.dptr = (uint8_t *)&uinttype;
4406 indata.dsize = sizeof(uinttype);
4408 ret = ctdb_control(ctdb, destnode, 0,
4409 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, indata,
4410 mem_ctx, &outdata, &res, &timeout, NULL);
4411 if (ret != 0 || res != 0) {
4412 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
4416 if (outdata.dsize == 0) {
4419 *scripts = (struct ctdb_script_list_old *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
4420 talloc_free(outdata.dptr);
4427 tell the main daemon how long it took to lock the reclock file
4429 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
4435 data.dptr = (uint8_t *)&latency;
4436 data.dsize = sizeof(latency);
4438 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
4439 ctdb, NULL, &res, NULL, NULL);
4440 if (ret != 0 || res != 0) {
4441 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
4449 get the name of the reclock file
4451 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
4452 uint32_t destnode, TALLOC_CTX *mem_ctx,
4459 ret = ctdb_control(ctdb, destnode, 0,
4460 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
4461 mem_ctx, &data, &res, &timeout, NULL);
4462 if (ret != 0 || res != 0) {
4466 if (data.dsize == 0) {
4469 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
4471 talloc_free(data.dptr);
4477 set the reclock filename for a node
4479 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
4485 if (reclock == NULL) {
4489 data.dsize = strlen(reclock) + 1;
4490 data.dptr = discard_const(reclock);
4493 ret = ctdb_control(ctdb, destnode, 0,
4494 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
4495 NULL, NULL, &res, &timeout, NULL);
4496 if (ret != 0 || res != 0) {
4497 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
4507 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4512 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
4513 ctdb, NULL, &res, &timeout, NULL);
4514 if (ret != 0 || res != 0) {
4515 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
4525 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
4529 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
4530 ctdb, NULL, NULL, &timeout, NULL);
4532 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
4540 set the natgw state for a node
4542 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
4548 data.dsize = sizeof(natgwstate);
4549 data.dptr = (uint8_t *)&natgwstate;
4551 ret = ctdb_control(ctdb, destnode, 0,
4552 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
4553 NULL, NULL, &res, &timeout, NULL);
4554 if (ret != 0 || res != 0) {
4555 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
4563 set the lmaster role for a node
4565 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
4571 data.dsize = sizeof(lmasterrole);
4572 data.dptr = (uint8_t *)&lmasterrole;
4574 ret = ctdb_control(ctdb, destnode, 0,
4575 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
4576 NULL, NULL, &res, &timeout, NULL);
4577 if (ret != 0 || res != 0) {
4578 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
4586 set the recmaster role for a node
4588 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
4594 data.dsize = sizeof(recmasterrole);
4595 data.dptr = (uint8_t *)&recmasterrole;
4597 ret = ctdb_control(ctdb, destnode, 0,
4598 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
4599 NULL, NULL, &res, &timeout, NULL);
4600 if (ret != 0 || res != 0) {
4601 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
4608 /* enable an eventscript
4610 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4616 data.dsize = strlen(script) + 1;
4617 data.dptr = discard_const(script);
4619 ret = ctdb_control(ctdb, destnode, 0,
4620 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
4621 NULL, NULL, &res, &timeout, NULL);
4622 if (ret != 0 || res != 0) {
4623 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
4630 /* disable an eventscript
4632 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
4638 data.dsize = strlen(script) + 1;
4639 data.dptr = discard_const(script);
4641 ret = ctdb_control(ctdb, destnode, 0,
4642 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
4643 NULL, NULL, &res, &timeout, NULL);
4644 if (ret != 0 || res != 0) {
4645 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
4653 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout,
4654 uint32_t destnode, struct ctdb_ban_state *bantime)
4660 data.dsize = sizeof(*bantime);
4661 data.dptr = (uint8_t *)bantime;
4663 ret = ctdb_control(ctdb, destnode, 0,
4664 CTDB_CONTROL_SET_BAN_STATE, 0, data,
4665 NULL, NULL, &res, &timeout, NULL);
4666 if (ret != 0 || res != 0) {
4667 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4675 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout,
4676 uint32_t destnode, TALLOC_CTX *mem_ctx,
4677 struct ctdb_ban_state **bantime)
4682 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4684 ret = ctdb_control(ctdb, destnode, 0,
4685 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
4686 tmp_ctx, &outdata, &res, &timeout, NULL);
4687 if (ret != 0 || res != 0) {
4688 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
4689 talloc_free(tmp_ctx);
4693 *bantime = (struct ctdb_ban_state *)talloc_steal(mem_ctx, outdata.dptr);
4694 talloc_free(tmp_ctx);
4700 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
4705 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4707 data.dptr = (uint8_t*)db_prio;
4708 data.dsize = sizeof(*db_prio);
4710 ret = ctdb_control(ctdb, destnode, 0,
4711 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
4712 tmp_ctx, NULL, &res, &timeout, NULL);
4713 if (ret != 0 || res != 0) {
4714 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
4715 talloc_free(tmp_ctx);
4719 talloc_free(tmp_ctx);
4724 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
4729 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
4731 data.dptr = (uint8_t*)&db_id;
4732 data.dsize = sizeof(db_id);
4734 ret = ctdb_control(ctdb, destnode, 0,
4735 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
4736 tmp_ctx, NULL, &res, &timeout, NULL);
4737 if (ret != 0 || res < 0) {
4738 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_db_priority failed\n"));
4739 talloc_free(tmp_ctx);
4747 talloc_free(tmp_ctx);
4752 int ctdb_ctrl_getstathistory(struct ctdb_context *ctdb,
4753 struct timeval timeout, uint32_t destnode,
4754 TALLOC_CTX *mem_ctx,
4755 struct ctdb_statistics_list_old **stats)
4761 ret = ctdb_control(ctdb, destnode, 0,
4762 CTDB_CONTROL_GET_STAT_HISTORY, 0, tdb_null,
4763 mem_ctx, &outdata, &res, &timeout, NULL);
4764 if (ret != 0 || res != 0 || outdata.dsize == 0) {
4765 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getstathistory failed ret:%d res:%d\n", ret, res));
4769 *stats = (struct ctdb_statistics_list_old *)talloc_memdup(mem_ctx,
4772 talloc_free(outdata.dptr);
4777 struct ctdb_ltdb_header *ctdb_header_from_record_handle(struct ctdb_record_handle *h)
4787 struct ctdb_client_control_state *
4788 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)
4790 struct ctdb_client_control_state *handle;
4791 struct ctdb_marshall_buffer *m;
4792 struct ctdb_rec_data_old *rec;
4795 m = talloc_zero(mem_ctx, struct ctdb_marshall_buffer);
4797 DEBUG(DEBUG_ERR, ("Failed to allocate marshall buffer for update record\n"));
4801 m->db_id = ctdb_db->db_id;
4803 rec = ctdb_marshall_record(m, 0, key, header, data);
4805 DEBUG(DEBUG_ERR,("Failed to marshall record for update record\n"));
4809 m = talloc_realloc_size(mem_ctx, m, rec->length + offsetof(struct ctdb_marshall_buffer, data));
4811 DEBUG(DEBUG_CRIT,(__location__ " Failed to expand recdata\n"));
4816 memcpy((uint8_t *)m + offsetof(struct ctdb_marshall_buffer, data), rec, rec->length);
4819 outdata.dptr = (uint8_t *)m;
4820 outdata.dsize = talloc_get_size(m);
4822 handle = ctdb_control_send(ctdb, destnode, 0,
4823 CTDB_CONTROL_UPDATE_RECORD, 0, outdata,
4824 mem_ctx, &timeout, NULL);
4829 int ctdb_ctrl_updaterecord_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4834 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
4835 if ( (ret != 0) || (res != 0) ){
4836 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_update_record_recv failed\n"));
4844 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)
4846 struct ctdb_client_control_state *state;
4848 state = ctdb_ctrl_updaterecord_send(ctdb, mem_ctx, timeout, destnode, ctdb_db, key, header, data);
4849 return ctdb_ctrl_updaterecord_recv(ctdb, state);
4858 set a database to be readonly
4860 struct ctdb_client_control_state *
4861 ctdb_ctrl_set_db_readonly_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4865 data.dptr = (uint8_t *)&dbid;
4866 data.dsize = sizeof(dbid);
4868 return ctdb_control_send(ctdb, destnode, 0,
4869 CTDB_CONTROL_SET_DB_READONLY, 0, data,
4873 int ctdb_ctrl_set_db_readonly_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4878 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4879 if (ret != 0 || res != 0) {
4880 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_readonly_recv failed ret:%d res:%d\n", ret, res));
4887 int ctdb_ctrl_set_db_readonly(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4889 struct ctdb_client_control_state *state;
4891 state = ctdb_ctrl_set_db_readonly_send(ctdb, destnode, dbid);
4892 return ctdb_ctrl_set_db_readonly_recv(ctdb, state);
4896 set a database to be sticky
4898 struct ctdb_client_control_state *
4899 ctdb_ctrl_set_db_sticky_send(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4903 data.dptr = (uint8_t *)&dbid;
4904 data.dsize = sizeof(dbid);
4906 return ctdb_control_send(ctdb, destnode, 0,
4907 CTDB_CONTROL_SET_DB_STICKY, 0, data,
4911 int ctdb_ctrl_set_db_sticky_recv(struct ctdb_context *ctdb, struct ctdb_client_control_state *state)
4916 ret = ctdb_control_recv(ctdb, state, ctdb, NULL, &res, NULL);
4917 if (ret != 0 || res != 0) {
4918 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_set_db_sticky_recv failed ret:%d res:%d\n", ret, res));
4925 int ctdb_ctrl_set_db_sticky(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid)
4927 struct ctdb_client_control_state *state;
4929 state = ctdb_ctrl_set_db_sticky_send(ctdb, destnode, dbid);
4930 return ctdb_ctrl_set_db_sticky_recv(ctdb, state);