4 Copyright (C) Andrew Tridgell 2007
5 Copyright (C) Ronnie Sahlberg 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "lib/tdb/include/tdb.h"
24 #include "lib/util/dlinklist.h"
25 #include "lib/events/events.h"
26 #include "system/network.h"
27 #include "system/filesys.h"
28 #include "system/locale.h"
30 #include "../include/ctdb_private.h"
31 #include "lib/util/dlinklist.h"
35 struct ctdb_record_handle {
36 struct ctdb_db_context *ctdb_db;
39 struct ctdb_ltdb_header header;
44 make a recv call to the local ctdb daemon - called from client context
46 This is called when the program wants to wait for a ctdb_call to complete and get the
47 results. This call will block unless the call has already completed.
49 int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
55 while (state->state < CTDB_CALL_DONE) {
56 event_loop_once(state->ctdb_db->ctdb->ev);
58 if (state->state != CTDB_CALL_DONE) {
59 DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
64 if (state->call->reply_data.dsize) {
65 call->reply_data.dptr = talloc_memdup(state->ctdb_db,
66 state->call->reply_data.dptr,
67 state->call->reply_data.dsize);
68 call->reply_data.dsize = state->call->reply_data.dsize;
70 call->reply_data.dptr = NULL;
71 call->reply_data.dsize = 0;
73 call->status = state->call->status;
86 full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
88 int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
90 struct ctdb_client_call_state *state;
92 state = ctdb_call_send(ctdb_db, call);
93 return ctdb_call_recv(state, call);
98 tell the daemon what messaging srvid we will use, and register the message
99 handler function in the client
101 int ctdb_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid,
102 ctdb_message_fn_t handler,
109 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_REGISTER_SRVID, 0,
110 tdb_null, NULL, NULL, &status, NULL, NULL);
111 if (res != 0 || status != 0) {
112 DEBUG(DEBUG_ERR,("Failed to register srvid %llu\n", (unsigned long long)srvid));
116 /* also need to register the handler with our own ctdb structure */
117 return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
121 tell the daemon we no longer want a srvid
123 int ctdb_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid, void *private_data)
128 res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_DEREGISTER_SRVID, 0,
129 tdb_null, NULL, NULL, &status, NULL, NULL);
130 if (res != 0 || status != 0) {
131 DEBUG(DEBUG_ERR,("Failed to deregister srvid %llu\n", (unsigned long long)srvid));
135 /* also need to register the handler with our own ctdb structure */
136 ctdb_deregister_message_handler(ctdb, srvid, private_data);
144 cancel a ctdb_fetch_lock operation, releasing the lock
146 static int fetch_lock_destructor(struct ctdb_record_handle *h)
148 ctdb_ltdb_unlock(h->ctdb_db, h->key);
153 force the migration of a record to this node
155 static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
157 struct ctdb_call call;
159 call.call_id = CTDB_NULL_FUNC;
161 call.flags = CTDB_IMMEDIATE_MIGRATION;
162 return ctdb_call(ctdb_db, &call);
166 get a lock on a record, and return the records data. Blocks until it gets the lock
168 struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
169 TDB_DATA key, TDB_DATA *data)
172 struct ctdb_record_handle *h;
175 procedure is as follows:
177 1) get the chain lock.
178 2) check if we are dmaster
179 3) if we are the dmaster then return handle
180 4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
182 5) when we get the reply, goto (1)
185 h = talloc_zero(mem_ctx, struct ctdb_record_handle);
190 h->ctdb_db = ctdb_db;
192 h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
193 if (h->key.dptr == NULL) {
199 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize,
200 (const char *)key.dptr));
203 /* step 1 - get the chain lock */
204 ret = ctdb_ltdb_lock(ctdb_db, key);
206 DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
211 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
213 talloc_set_destructor(h, fetch_lock_destructor);
215 ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
217 /* when torturing, ensure we test the remote path */
218 if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
220 h->header.dmaster = (uint32_t)-1;
224 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
226 if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
227 ctdb_ltdb_unlock(ctdb_db, key);
228 ret = ctdb_client_force_migration(ctdb_db, key);
230 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
237 DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
242 store some data to the record that was locked with ctdb_fetch_lock()
244 int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
246 if (h->ctdb_db->persistent) {
247 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
251 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
255 non-locking fetch of a record
257 int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx,
258 TDB_DATA key, TDB_DATA *data)
260 struct ctdb_call call;
263 call.call_id = CTDB_FETCH_FUNC;
264 call.call_data.dptr = NULL;
265 call.call_data.dsize = 0;
267 ret = ctdb_call(ctdb_db, &call);
270 *data = call.reply_data;
271 talloc_steal(mem_ctx, data->dptr);
285 send a ctdb control message
286 timeout specifies how long we should wait for a reply.
287 if timeout is NULL we wait indefinitely
289 int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid,
290 uint32_t opcode, uint32_t flags, TDB_DATA data,
291 TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
292 struct timeval *timeout,
295 struct ctdb_client_control_state *state;
297 state = ctdb_control_send(ctdb, destnode, srvid, opcode,
298 flags, data, mem_ctx,
300 return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status,
308 a process exists call. Returns 0 if process exists, -1 otherwise
310 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
316 data.dptr = (uint8_t*)&pid;
317 data.dsize = sizeof(pid);
319 ret = ctdb_control(ctdb, destnode, 0,
320 CTDB_CONTROL_PROCESS_EXISTS, 0, data,
321 NULL, NULL, &status, NULL, NULL);
323 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
331 get remote statistics
333 int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
339 ret = ctdb_control(ctdb, destnode, 0,
340 CTDB_CONTROL_STATISTICS, 0, tdb_null,
341 ctdb, &data, &res, NULL, NULL);
342 if (ret != 0 || res != 0) {
343 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
347 if (data.dsize != sizeof(struct ctdb_statistics)) {
348 DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
349 (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
353 *status = *(struct ctdb_statistics *)data.dptr;
354 talloc_free(data.dptr);
360 shutdown a remote ctdb node
362 int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
364 struct ctdb_client_control_state *state;
366 state = ctdb_control_send(ctdb, destnode, 0,
367 CTDB_CONTROL_SHUTDOWN, 0, tdb_null,
368 NULL, &timeout, NULL);
370 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
378 get vnn map from a remote node
380 int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
385 struct ctdb_vnn_map_wire *map;
387 ret = ctdb_control(ctdb, destnode, 0,
388 CTDB_CONTROL_GETVNNMAP, 0, tdb_null,
389 mem_ctx, &outdata, &res, &timeout, NULL);
390 if (ret != 0 || res != 0) {
391 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
395 map = (struct ctdb_vnn_map_wire *)outdata.dptr;
396 if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
397 outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
398 DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
402 (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
403 CTDB_NO_MEMORY(ctdb, *vnnmap);
404 (*vnnmap)->generation = map->generation;
405 (*vnnmap)->size = map->size;
406 (*vnnmap)->map = talloc_array(*vnnmap, uint32_t, map->size);
408 CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
409 memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
410 talloc_free(outdata.dptr);
417 get the recovery mode of a remote node
419 struct ctdb_client_control_state *
420 ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
422 return ctdb_control_send(ctdb, destnode, 0,
423 CTDB_CONTROL_GET_RECMODE, 0, tdb_null,
424 mem_ctx, &timeout, NULL);
427 int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
432 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
434 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
439 *recmode = (uint32_t)res;
445 int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
447 struct ctdb_client_control_state *state;
449 state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
450 return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
457 set the recovery mode of a remote node
459 int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
465 data.dsize = sizeof(uint32_t);
466 data.dptr = (unsigned char *)&recmode;
468 ret = ctdb_control(ctdb, destnode, 0,
469 CTDB_CONTROL_SET_RECMODE, 0, data,
470 NULL, NULL, &res, &timeout, NULL);
471 if (ret != 0 || res != 0) {
472 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
482 get the recovery master of a remote node
484 struct ctdb_client_control_state *
485 ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx,
486 struct timeval timeout, uint32_t destnode)
488 return ctdb_control_send(ctdb, destnode, 0,
489 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
490 mem_ctx, &timeout, NULL);
493 int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
498 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
500 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
505 *recmaster = (uint32_t)res;
511 int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
513 struct ctdb_client_control_state *state;
515 state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
516 return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
521 set the recovery master of a remote node
523 int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
530 data.dsize = sizeof(uint32_t);
531 data.dptr = (unsigned char *)&recmaster;
533 ret = ctdb_control(ctdb, destnode, 0,
534 CTDB_CONTROL_SET_RECMASTER, 0, data,
535 NULL, NULL, &res, &timeout, NULL);
536 if (ret != 0 || res != 0) {
537 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
546 get a list of databases off a remote node
548 int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
549 TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
555 ret = ctdb_control(ctdb, destnode, 0,
556 CTDB_CONTROL_GET_DBMAP, 0, tdb_null,
557 mem_ctx, &outdata, &res, &timeout, NULL);
558 if (ret != 0 || res != 0) {
559 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
563 *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
564 talloc_free(outdata.dptr);
570 get a list of nodes (vnn and flags ) from a remote node
572 int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
573 struct timeval timeout, uint32_t destnode,
574 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
580 ret = ctdb_control(ctdb, destnode, 0,
581 CTDB_CONTROL_GET_NODEMAP, 0, tdb_null,
582 mem_ctx, &outdata, &res, &timeout, NULL);
583 if (ret == 0 && res == -1 && outdata.dsize == 0) {
584 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
585 return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
587 if (ret != 0 || res != 0 || outdata.dsize == 0) {
588 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
592 *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
593 talloc_free(outdata.dptr);
599 old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
601 int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb,
602 struct timeval timeout, uint32_t destnode,
603 TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
607 struct ctdb_node_mapv4 *nodemapv4;
610 ret = ctdb_control(ctdb, destnode, 0,
611 CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null,
612 mem_ctx, &outdata, &res, &timeout, NULL);
613 if (ret != 0 || res != 0 || outdata.dsize == 0) {
614 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
618 nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
620 len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
621 (*nodemap) = talloc_zero_size(mem_ctx, len);
622 CTDB_NO_MEMORY(ctdb, (*nodemap));
624 (*nodemap)->num = nodemapv4->num;
625 for (i=0; i<nodemapv4->num; i++) {
626 (*nodemap)->nodes[i].pnn = nodemapv4->nodes[i].pnn;
627 (*nodemap)->nodes[i].flags = nodemapv4->nodes[i].flags;
628 (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
629 (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
632 talloc_free(outdata.dptr);
638 drop the transport, reload the nodes file and restart the transport
640 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb,
641 struct timeval timeout, uint32_t destnode)
646 ret = ctdb_control(ctdb, destnode, 0,
647 CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null,
648 NULL, NULL, &res, &timeout, NULL);
649 if (ret != 0 || res != 0) {
650 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
659 set vnn map on a node
661 int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
662 TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
667 struct ctdb_vnn_map_wire *map;
670 len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
671 map = talloc_size(mem_ctx, len);
672 CTDB_NO_MEMORY(ctdb, map);
674 map->generation = vnnmap->generation;
675 map->size = vnnmap->size;
676 memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
679 data.dptr = (uint8_t *)map;
681 ret = ctdb_control(ctdb, destnode, 0,
682 CTDB_CONTROL_SETVNNMAP, 0, data,
683 NULL, NULL, &res, &timeout, NULL);
684 if (ret != 0 || res != 0) {
685 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
696 async send for pull database
698 struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
699 struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
700 uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
703 struct ctdb_control_pulldb *pull;
704 struct ctdb_client_control_state *state;
706 pull = talloc(mem_ctx, struct ctdb_control_pulldb);
707 CTDB_NO_MEMORY_NULL(ctdb, pull);
710 pull->lmaster = lmaster;
712 indata.dsize = sizeof(struct ctdb_control_pulldb);
713 indata.dptr = (unsigned char *)pull;
715 state = ctdb_control_send(ctdb, destnode, 0,
716 CTDB_CONTROL_PULL_DB, 0, indata,
717 mem_ctx, &timeout, NULL);
724 async recv for pull database
726 int ctdb_ctrl_pulldb_recv(
727 struct ctdb_context *ctdb,
728 TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state,
734 ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
735 if ( (ret != 0) || (res != 0) ){
736 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
744 pull all keys and records for a specific database on a node
746 int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode,
747 uint32_t dbid, uint32_t lmaster,
748 TALLOC_CTX *mem_ctx, struct timeval timeout,
751 struct ctdb_client_control_state *state;
753 state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
756 return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
761 change dmaster for all keys in the database to the new value
763 int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
764 TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
770 indata.dsize = 2*sizeof(uint32_t);
771 indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
773 ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
774 ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
776 ret = ctdb_control(ctdb, destnode, 0,
777 CTDB_CONTROL_SET_DMASTER, 0, indata,
778 NULL, NULL, &res, &timeout, NULL);
779 if (ret != 0 || res != 0) {
780 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
788 ping a node, return number of clients connected
790 int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
795 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0,
796 tdb_null, NULL, NULL, &res, NULL, NULL);
804 find the real path to a ltdb
806 int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
813 data.dptr = (uint8_t *)&dbid;
814 data.dsize = sizeof(dbid);
816 ret = ctdb_control(ctdb, destnode, 0,
817 CTDB_CONTROL_GETDBPATH, 0, data,
818 mem_ctx, &data, &res, &timeout, NULL);
819 if (ret != 0 || res != 0) {
823 (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
824 if ((*path) == NULL) {
828 talloc_free(data.dptr);
834 find the name of a db
836 int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx,
843 data.dptr = (uint8_t *)&dbid;
844 data.dsize = sizeof(dbid);
846 ret = ctdb_control(ctdb, destnode, 0,
847 CTDB_CONTROL_GET_DBNAME, 0, data,
848 mem_ctx, &data, &res, &timeout, NULL);
849 if (ret != 0 || res != 0) {
853 (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
854 if ((*name) == NULL) {
858 talloc_free(data.dptr);
864 get the health status of a db
866 int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
867 struct timeval timeout,
869 uint32_t dbid, TALLOC_CTX *mem_ctx,
876 data.dptr = (uint8_t *)&dbid;
877 data.dsize = sizeof(dbid);
879 ret = ctdb_control(ctdb, destnode, 0,
880 CTDB_CONTROL_DB_GET_HEALTH, 0, data,
881 mem_ctx, &data, &res, &timeout, NULL);
882 if (ret != 0 || res != 0) {
886 if (data.dsize == 0) {
891 (*reason) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
892 if ((*reason) == NULL) {
896 talloc_free(data.dptr);
904 int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
905 TALLOC_CTX *mem_ctx, const char *name, bool persistent)
911 data.dptr = discard_const(name);
912 data.dsize = strlen(name)+1;
914 ret = ctdb_control(ctdb, destnode, 0,
915 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
917 mem_ctx, &data, &res, &timeout, NULL);
919 if (ret != 0 || res != 0) {
927 get debug level on a node
929 int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
935 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null,
936 ctdb, &data, &res, NULL, NULL);
937 if (ret != 0 || res != 0) {
940 if (data.dsize != sizeof(int32_t)) {
941 DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
942 (unsigned)data.dsize));
945 *level = *(int32_t *)data.dptr;
946 talloc_free(data.dptr);
951 set debug level on a node
953 int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
959 data.dptr = (uint8_t *)&level;
960 data.dsize = sizeof(level);
962 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data,
963 NULL, NULL, &res, NULL, NULL);
964 if (ret != 0 || res != 0) {
972 get a list of connected nodes
974 uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb,
975 struct timeval timeout,
979 struct ctdb_node_map *map=NULL;
985 ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
990 nodes = talloc_array(mem_ctx, uint32_t, map->num);
995 for (i=0;i<map->num;i++) {
996 if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
997 nodes[*num_nodes] = map->nodes[i].pnn;
1009 int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
1014 ret = ctdb_control(ctdb, destnode, 0,
1015 CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null,
1016 NULL, NULL, &res, NULL, NULL);
1017 if (ret != 0 || res != 0) {
1018 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
1025 this is the dummy null procedure that all databases support
1027 static int ctdb_null_func(struct ctdb_call_info *call)
1033 this is a plain fetch procedure that all databases support
1035 static int ctdb_fetch_func(struct ctdb_call_info *call)
1037 call->reply_data = &call->record_data;
1042 attach to a specific database - client call
1044 struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name, bool persistent, uint32_t tdb_flags)
1046 struct ctdb_db_context *ctdb_db;
1051 ctdb_db = ctdb_db_handle(ctdb, name);
1056 ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
1057 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
1059 ctdb_db->ctdb = ctdb;
1060 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
1061 CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
1063 data.dptr = discard_const(name);
1064 data.dsize = strlen(name)+1;
1066 /* tell ctdb daemon to attach */
1067 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags,
1068 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
1069 0, data, ctdb_db, &data, &res, NULL, NULL);
1070 if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
1071 DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
1072 talloc_free(ctdb_db);
1076 ctdb_db->db_id = *(uint32_t *)data.dptr;
1077 talloc_free(data.dptr);
1079 ret = ctdb_ctrl_getdbpath(ctdb, timeval_current_ofs(2, 0), CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
1081 DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
1082 talloc_free(ctdb_db);
1086 tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
1087 if (ctdb->valgrinding) {
1088 tdb_flags |= TDB_NOMMAP;
1090 tdb_flags |= TDB_DISALLOW_NESTING;
1092 ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
1093 if (ctdb_db->ltdb == NULL) {
1094 ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
1095 talloc_free(ctdb_db);
1099 ctdb_db->persistent = persistent;
1101 DLIST_ADD(ctdb->db_list, ctdb_db);
1103 /* add well known functions */
1104 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
1105 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
1112 setup a call for a database
1114 int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
1116 struct ctdb_registered_call *call;
1121 struct ctdb_control_set_call c;
1124 /* this is no longer valid with the separate daemon architecture */
1125 c.db_id = ctdb_db->db_id;
1129 data.dptr = (uint8_t *)&c;
1130 data.dsize = sizeof(c);
1132 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_SET_CALL, 0,
1133 data, NULL, NULL, &status, NULL, NULL);
1134 if (ret != 0 || status != 0) {
1135 DEBUG(DEBUG_ERR,("ctdb_set_call failed for call %u\n", id));
1140 /* also register locally */
1141 call = talloc(ctdb_db, struct ctdb_registered_call);
1145 DLIST_ADD(ctdb_db->calls, call);
1150 struct traverse_state {
1153 ctdb_traverse_func fn;
1158 called on each key during a ctdb_traverse
1160 static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p)
1162 struct traverse_state *state = (struct traverse_state *)p;
1163 struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
1166 if (data.dsize < sizeof(uint32_t) ||
1167 d->length != data.dsize) {
1168 DEBUG(DEBUG_ERR,("Bad data size %u in traverse_handler\n", (unsigned)data.dsize));
1173 key.dsize = d->keylen;
1174 key.dptr = &d->data[0];
1175 data.dsize = d->datalen;
1176 data.dptr = &d->data[d->keylen];
1178 if (key.dsize == 0 && data.dsize == 0) {
1179 /* end of traverse */
1184 if (data.dsize == sizeof(struct ctdb_ltdb_header)) {
1185 /* empty records are deleted records in ctdb */
1189 if (state->fn(ctdb, key, data, state->private_data) != 0) {
1198 start a cluster wide traverse, calling the supplied fn on each record
1199 return the number of records traversed, or -1 on error
1201 int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
1204 struct ctdb_traverse_start t;
1207 uint64_t srvid = (getpid() | 0xFLL<<60);
1208 struct traverse_state state;
1212 state.private_data = private_data;
1215 ret = ctdb_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
1217 DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
1221 t.db_id = ctdb_db->db_id;
1225 data.dptr = (uint8_t *)&t;
1226 data.dsize = sizeof(t);
1228 ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START, 0,
1229 data, NULL, NULL, &status, NULL, NULL);
1230 if (ret != 0 || status != 0) {
1231 DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
1232 ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state);
1236 while (!state.done) {
1237 event_loop_once(ctdb_db->ctdb->ev);
1240 ret = ctdb_remove_message_handler(ctdb_db->ctdb, srvid, &state);
1242 DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
1249 #define ISASCII(x) ((x>31)&&(x<128))
1251 called on each key during a catdb
1253 int ctdb_dumpdb_record(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p)
1256 FILE *f = (FILE *)p;
1257 struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
1259 fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
1260 for (i=0;i<key.dsize;i++) {
1261 if (ISASCII(key.dptr[i])) {
1262 fprintf(f, "%c", key.dptr[i]);
1264 fprintf(f, "\\%02X", key.dptr[i]);
1269 fprintf(f, "dmaster: %u\n", h->dmaster);
1270 fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
1272 fprintf(f, "data(%u) = \"", (unsigned)(data.dsize - sizeof(*h)));
1273 for (i=sizeof(*h);i<data.dsize;i++) {
1274 if (ISASCII(data.dptr[i])) {
1275 fprintf(f, "%c", data.dptr[i]);
1277 fprintf(f, "\\%02X", data.dptr[i]);
1288 convenience function to list all keys to stdout
1290 int ctdb_dump_db(struct ctdb_db_context *ctdb_db, FILE *f)
1292 return ctdb_traverse(ctdb_db, ctdb_dumpdb_record, f);
1296 get the pid of a ctdb daemon
1298 int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
1303 ret = ctdb_control(ctdb, destnode, 0,
1304 CTDB_CONTROL_GET_PID, 0, tdb_null,
1305 NULL, NULL, &res, &timeout, NULL);
1307 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
1318 async freeze send control
1320 struct ctdb_client_control_state *
1321 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
1323 return ctdb_control_send(ctdb, destnode, priority,
1324 CTDB_CONTROL_FREEZE, 0, tdb_null,
1325 mem_ctx, &timeout, NULL);
1329 async freeze recv control
1331 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
1336 ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
1337 if ( (ret != 0) || (res != 0) ){
1338 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
1346 freeze databases of a certain priority
1348 int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
1350 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1351 struct ctdb_client_control_state *state;
1354 state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
1355 ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
1356 talloc_free(tmp_ctx);
1361 /* Freeze all databases */
1362 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1366 for (i=1; i<=NUM_DB_PRIORITIES; i++) {
1367 if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
1375 thaw databases of a certain priority
1377 int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
1382 ret = ctdb_control(ctdb, destnode, priority,
1383 CTDB_CONTROL_THAW, 0, tdb_null,
1384 NULL, NULL, &res, &timeout, NULL);
1385 if (ret != 0 || res != 0) {
1386 DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
1393 /* thaw all databases */
1394 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1396 return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
1400 get pnn of a node, or -1
1402 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1407 ret = ctdb_control(ctdb, destnode, 0,
1408 CTDB_CONTROL_GET_PNN, 0, tdb_null,
1409 NULL, NULL, &res, &timeout, NULL);
1411 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
1419 get the monitoring mode of a remote node
1421 int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
1426 ret = ctdb_control(ctdb, destnode, 0,
1427 CTDB_CONTROL_GET_MONMODE, 0, tdb_null,
1428 NULL, NULL, &res, &timeout, NULL);
1430 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
1441 set the monitoring mode of a remote node to active
1443 int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1448 ret = ctdb_control(ctdb, destnode, 0,
1449 CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null,
1450 NULL, NULL,NULL, &timeout, NULL);
1452 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
1462 set the monitoring mode of a remote node to disable
1464 int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
1469 ret = ctdb_control(ctdb, destnode, 0,
1470 CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null,
1471 NULL, NULL, NULL, &timeout, NULL);
1473 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
1485 sent to a node to make it take over an ip address
1487 int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout,
1488 uint32_t destnode, struct ctdb_public_ip *ip)
1491 struct ctdb_public_ipv4 ipv4;
1495 if (ip->addr.sa.sa_family == AF_INET) {
1497 ipv4.sin = ip->addr.ip;
1499 data.dsize = sizeof(ipv4);
1500 data.dptr = (uint8_t *)&ipv4;
1502 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
1503 NULL, &res, &timeout, NULL);
1505 data.dsize = sizeof(*ip);
1506 data.dptr = (uint8_t *)ip;
1508 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
1509 NULL, &res, &timeout, NULL);
1512 if (ret != 0 || res != 0) {
1513 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
1522 sent to a node to make it release an ip address
1524 int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout,
1525 uint32_t destnode, struct ctdb_public_ip *ip)
1528 struct ctdb_public_ipv4 ipv4;
1532 if (ip->addr.sa.sa_family == AF_INET) {
1534 ipv4.sin = ip->addr.ip;
1536 data.dsize = sizeof(ipv4);
1537 data.dptr = (uint8_t *)&ipv4;
1539 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
1540 NULL, &res, &timeout, NULL);
1542 data.dsize = sizeof(*ip);
1543 data.dptr = (uint8_t *)ip;
1545 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
1546 NULL, &res, &timeout, NULL);
1549 if (ret != 0 || res != 0) {
1550 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
1561 int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb,
1562 struct timeval timeout,
1564 const char *name, uint32_t *value)
1566 struct ctdb_control_get_tunable *t;
1567 TDB_DATA data, outdata;
1571 data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
1572 data.dptr = talloc_size(ctdb, data.dsize);
1573 CTDB_NO_MEMORY(ctdb, data.dptr);
1575 t = (struct ctdb_control_get_tunable *)data.dptr;
1576 t->length = strlen(name)+1;
1577 memcpy(t->name, name, t->length);
1579 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
1580 &outdata, &res, &timeout, NULL);
1581 talloc_free(data.dptr);
1582 if (ret != 0 || res != 0) {
1583 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
1587 if (outdata.dsize != sizeof(uint32_t)) {
1588 DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
1589 talloc_free(outdata.dptr);
1593 *value = *(uint32_t *)outdata.dptr;
1594 talloc_free(outdata.dptr);
1602 int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb,
1603 struct timeval timeout,
1605 const char *name, uint32_t value)
1607 struct ctdb_control_set_tunable *t;
1612 data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
1613 data.dptr = talloc_size(ctdb, data.dsize);
1614 CTDB_NO_MEMORY(ctdb, data.dptr);
1616 t = (struct ctdb_control_set_tunable *)data.dptr;
1617 t->length = strlen(name)+1;
1618 memcpy(t->name, name, t->length);
1621 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
1622 NULL, &res, &timeout, NULL);
1623 talloc_free(data.dptr);
1624 if (ret != 0 || res != 0) {
1625 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
1635 int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb,
1636 struct timeval timeout,
1638 TALLOC_CTX *mem_ctx,
1639 const char ***list, uint32_t *count)
1644 struct ctdb_control_list_tunable *t;
1647 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null,
1648 mem_ctx, &outdata, &res, &timeout, NULL);
1649 if (ret != 0 || res != 0) {
1650 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
1654 t = (struct ctdb_control_list_tunable *)outdata.dptr;
1655 if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
1656 t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
1657 DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
1658 talloc_free(outdata.dptr);
1662 p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
1663 CTDB_NO_MEMORY(ctdb, p);
1665 talloc_free(outdata.dptr);
1670 for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
1671 (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
1672 CTDB_NO_MEMORY(ctdb, *list);
1673 (*list)[*count] = talloc_strdup(*list, s);
1674 CTDB_NO_MEMORY(ctdb, (*list)[*count]);
1684 int ctdb_ctrl_get_public_ips_flags(struct ctdb_context *ctdb,
1685 struct timeval timeout, uint32_t destnode,
1686 TALLOC_CTX *mem_ctx,
1688 struct ctdb_all_public_ips **ips)
1694 ret = ctdb_control(ctdb, destnode, 0,
1695 CTDB_CONTROL_GET_PUBLIC_IPS, flags, tdb_null,
1696 mem_ctx, &outdata, &res, &timeout, NULL);
1697 if (ret == 0 && res == -1) {
1698 DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
1699 return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
1701 if (ret != 0 || res != 0) {
1702 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
1706 *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
1707 talloc_free(outdata.dptr);
1712 int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
1713 struct timeval timeout, uint32_t destnode,
1714 TALLOC_CTX *mem_ctx,
1715 struct ctdb_all_public_ips **ips)
1717 return ctdb_ctrl_get_public_ips_flags(ctdb, timeout,
1722 int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
1723 struct timeval timeout, uint32_t destnode,
1724 TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
1729 struct ctdb_all_public_ipsv4 *ipsv4;
1731 ret = ctdb_control(ctdb, destnode, 0,
1732 CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null,
1733 mem_ctx, &outdata, &res, &timeout, NULL);
1734 if (ret != 0 || res != 0) {
1735 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
1739 ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
1740 len = offsetof(struct ctdb_all_public_ips, ips) +
1741 ipsv4->num*sizeof(struct ctdb_public_ip);
1742 *ips = talloc_zero_size(mem_ctx, len);
1743 CTDB_NO_MEMORY(ctdb, *ips);
1744 (*ips)->num = ipsv4->num;
1745 for (i=0; i<ipsv4->num; i++) {
1746 (*ips)->ips[i].pnn = ipsv4->ips[i].pnn;
1747 (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
1750 talloc_free(outdata.dptr);
1755 int ctdb_ctrl_get_public_ip_info(struct ctdb_context *ctdb,
1756 struct timeval timeout, uint32_t destnode,
1757 TALLOC_CTX *mem_ctx,
1758 const ctdb_sock_addr *addr,
1759 struct ctdb_control_public_ip_info **_info)
1765 struct ctdb_control_public_ip_info *info;
1769 indata.dptr = discard_const_p(uint8_t, addr);
1770 indata.dsize = sizeof(*addr);
1772 ret = ctdb_control(ctdb, destnode, 0,
1773 CTDB_CONTROL_GET_PUBLIC_IP_INFO, 0, indata,
1774 mem_ctx, &outdata, &res, &timeout, NULL);
1775 if (ret != 0 || res != 0) {
1776 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
1777 "failed ret:%d res:%d\n",
1782 len = offsetof(struct ctdb_control_public_ip_info, ifaces);
1783 if (len > outdata.dsize) {
1784 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
1785 "returned invalid data with size %u > %u\n",
1786 (unsigned int)outdata.dsize,
1787 (unsigned int)len));
1788 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
1792 info = (struct ctdb_control_public_ip_info *)outdata.dptr;
1793 len += info->num*sizeof(struct ctdb_control_iface_info);
1795 if (len > outdata.dsize) {
1796 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
1797 "returned invalid data with size %u > %u\n",
1798 (unsigned int)outdata.dsize,
1799 (unsigned int)len));
1800 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
1804 /* make sure we null terminate the returned strings */
1805 for (i=0; i < info->num; i++) {
1806 info->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
1809 *_info = (struct ctdb_control_public_ip_info *)talloc_memdup(mem_ctx,
1812 talloc_free(outdata.dptr);
1813 if (*_info == NULL) {
1814 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
1815 "talloc_memdup size %u failed\n",
1816 (unsigned int)outdata.dsize));
1823 int ctdb_ctrl_get_ifaces(struct ctdb_context *ctdb,
1824 struct timeval timeout, uint32_t destnode,
1825 TALLOC_CTX *mem_ctx,
1826 struct ctdb_control_get_ifaces **_ifaces)
1831 struct ctdb_control_get_ifaces *ifaces;
1835 ret = ctdb_control(ctdb, destnode, 0,
1836 CTDB_CONTROL_GET_IFACES, 0, tdb_null,
1837 mem_ctx, &outdata, &res, &timeout, NULL);
1838 if (ret != 0 || res != 0) {
1839 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
1840 "failed ret:%d res:%d\n",
1845 len = offsetof(struct ctdb_control_get_ifaces, ifaces);
1846 if (len > outdata.dsize) {
1847 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
1848 "returned invalid data with size %u > %u\n",
1849 (unsigned int)outdata.dsize,
1850 (unsigned int)len));
1851 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
1855 ifaces = (struct ctdb_control_get_ifaces *)outdata.dptr;
1856 len += ifaces->num*sizeof(struct ctdb_control_iface_info);
1858 if (len > outdata.dsize) {
1859 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
1860 "returned invalid data with size %u > %u\n",
1861 (unsigned int)outdata.dsize,
1862 (unsigned int)len));
1863 dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
1867 /* make sure we null terminate the returned strings */
1868 for (i=0; i < ifaces->num; i++) {
1869 ifaces->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
1872 *_ifaces = (struct ctdb_control_get_ifaces *)talloc_memdup(mem_ctx,
1875 talloc_free(outdata.dptr);
1876 if (*_ifaces == NULL) {
1877 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
1878 "talloc_memdup size %u failed\n",
1879 (unsigned int)outdata.dsize));
1886 int ctdb_ctrl_set_iface_link(struct ctdb_context *ctdb,
1887 struct timeval timeout, uint32_t destnode,
1888 TALLOC_CTX *mem_ctx,
1889 const struct ctdb_control_iface_info *info)
1895 indata.dptr = discard_const_p(uint8_t, info);
1896 indata.dsize = sizeof(*info);
1898 ret = ctdb_control(ctdb, destnode, 0,
1899 CTDB_CONTROL_SET_IFACE_LINK_STATE, 0, indata,
1900 mem_ctx, NULL, &res, &timeout, NULL);
1901 if (ret != 0 || res != 0) {
1902 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set iface link "
1903 "failed ret:%d res:%d\n",
1912 set/clear the permanent disabled bit on a remote node
1914 int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
1915 uint32_t set, uint32_t clear)
1919 struct ctdb_node_map *nodemap=NULL;
1920 struct ctdb_node_flag_change c;
1921 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
1926 /* find the recovery master */
1927 ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
1929 DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
1930 talloc_free(tmp_ctx);
1935 /* read the node flags from the recmaster */
1936 ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
1938 DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
1939 talloc_free(tmp_ctx);
1942 if (destnode >= nodemap->num) {
1943 DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
1944 talloc_free(tmp_ctx);
1949 c.old_flags = nodemap->nodes[destnode].flags;
1950 c.new_flags = c.old_flags;
1952 c.new_flags &= ~clear;
1954 data.dsize = sizeof(c);
1955 data.dptr = (unsigned char *)&c;
1957 /* send the flags update to all connected nodes */
1958 nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
1960 if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
1962 timeout, false, data,
1965 DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
1967 talloc_free(tmp_ctx);
1971 talloc_free(tmp_ctx);
1979 int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
1980 struct timeval timeout,
1982 struct ctdb_tunable *tunables)
1988 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
1989 &outdata, &res, &timeout, NULL);
1990 if (ret != 0 || res != 0) {
1991 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
1995 if (outdata.dsize != sizeof(*tunables)) {
1996 DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
1997 (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
2001 *tunables = *(struct ctdb_tunable *)outdata.dptr;
2002 talloc_free(outdata.dptr);
2007 add a public address to a node
2009 int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb,
2010 struct timeval timeout,
2012 struct ctdb_control_ip_iface *pub)
2018 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2019 data.dptr = (unsigned char *)pub;
2021 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
2022 NULL, &res, &timeout, NULL);
2023 if (ret != 0 || res != 0) {
2024 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
2032 delete a public address from a node
2034 int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb,
2035 struct timeval timeout,
2037 struct ctdb_control_ip_iface *pub)
2043 data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
2044 data.dptr = (unsigned char *)pub;
2046 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
2047 NULL, &res, &timeout, NULL);
2048 if (ret != 0 || res != 0) {
2049 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
2057 kill a tcp connection
2059 int ctdb_ctrl_killtcp(struct ctdb_context *ctdb,
2060 struct timeval timeout,
2062 struct ctdb_control_killtcp *killtcp)
2068 data.dsize = sizeof(struct ctdb_control_killtcp);
2069 data.dptr = (unsigned char *)killtcp;
2071 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_KILL_TCP, 0, data, NULL,
2072 NULL, &res, &timeout, NULL);
2073 if (ret != 0 || res != 0) {
2074 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for killtcp failed\n"));
2084 int ctdb_ctrl_gratious_arp(struct ctdb_context *ctdb,
2085 struct timeval timeout,
2087 ctdb_sock_addr *addr,
2093 struct ctdb_control_gratious_arp *gratious_arp;
2094 TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
2097 len = strlen(ifname)+1;
2098 gratious_arp = talloc_size(tmp_ctx,
2099 offsetof(struct ctdb_control_gratious_arp, iface) + len);
2100 CTDB_NO_MEMORY(ctdb, gratious_arp);
2102 gratious_arp->addr = *addr;
2103 gratious_arp->len = len;
2104 memcpy(&gratious_arp->iface[0], ifname, len);
2107 data.dsize = offsetof(struct ctdb_control_gratious_arp, iface) + len;
2108 data.dptr = (unsigned char *)gratious_arp;
2110 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SEND_GRATIOUS_ARP, 0, data, NULL,
2111 NULL, &res, &timeout, NULL);
2112 if (ret != 0 || res != 0) {
2113 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for gratious_arp failed\n"));
2114 talloc_free(tmp_ctx);
2118 talloc_free(tmp_ctx);
2123 get a list of all tcp tickles that a node knows about for a particular vnn
2125 int ctdb_ctrl_get_tcp_tickles(struct ctdb_context *ctdb,
2126 struct timeval timeout, uint32_t destnode,
2127 TALLOC_CTX *mem_ctx,
2128 ctdb_sock_addr *addr,
2129 struct ctdb_control_tcp_tickle_list **list)
2132 TDB_DATA data, outdata;
2135 data.dptr = (uint8_t*)addr;
2136 data.dsize = sizeof(ctdb_sock_addr);
2138 ret = ctdb_control(ctdb, destnode, 0,
2139 CTDB_CONTROL_GET_TCP_TICKLE_LIST, 0, data,
2140 mem_ctx, &outdata, &status, NULL, NULL);
2141 if (ret != 0 || status != 0) {
2142 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get tcp tickles failed\n"));
2146 *list = (struct ctdb_control_tcp_tickle_list *)outdata.dptr;
2152 register a server id
2154 int ctdb_ctrl_register_server_id(struct ctdb_context *ctdb,
2155 struct timeval timeout,
2156 struct ctdb_server_id *id)
2162 data.dsize = sizeof(struct ctdb_server_id);
2163 data.dptr = (unsigned char *)id;
2165 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2166 CTDB_CONTROL_REGISTER_SERVER_ID,
2168 NULL, &res, &timeout, NULL);
2169 if (ret != 0 || res != 0) {
2170 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for register server id failed\n"));
2178 unregister a server id
2180 int ctdb_ctrl_unregister_server_id(struct ctdb_context *ctdb,
2181 struct timeval timeout,
2182 struct ctdb_server_id *id)
2188 data.dsize = sizeof(struct ctdb_server_id);
2189 data.dptr = (unsigned char *)id;
2191 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0,
2192 CTDB_CONTROL_UNREGISTER_SERVER_ID,
2194 NULL, &res, &timeout, NULL);
2195 if (ret != 0 || res != 0) {
2196 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for unregister server id failed\n"));
2205 check if a server id exists
2207 if a server id does exist, return *status == 1, otherwise *status == 0
2209 int ctdb_ctrl_check_server_id(struct ctdb_context *ctdb,
2210 struct timeval timeout,
2212 struct ctdb_server_id *id,
2219 data.dsize = sizeof(struct ctdb_server_id);
2220 data.dptr = (unsigned char *)id;
2222 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CHECK_SERVER_ID,
2224 NULL, &res, &timeout, NULL);
2226 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for check server id failed\n"));
2240 get the list of server ids that are registered on a node
2242 int ctdb_ctrl_get_server_id_list(struct ctdb_context *ctdb,
2243 TALLOC_CTX *mem_ctx,
2244 struct timeval timeout, uint32_t destnode,
2245 struct ctdb_server_id_list **svid_list)
2251 ret = ctdb_control(ctdb, destnode, 0,
2252 CTDB_CONTROL_GET_SERVER_ID_LIST, 0, tdb_null,
2253 mem_ctx, &outdata, &res, &timeout, NULL);
2254 if (ret != 0 || res != 0) {
2255 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_server_id_list failed\n"));
2259 *svid_list = (struct ctdb_server_id_list *)talloc_steal(mem_ctx, outdata.dptr);
2265 initialise the ctdb daemon for client applications
2267 NOTE: In current code the daemon does not fork. This is for testing purposes only
2268 and to simplify the code.
2270 struct ctdb_context *ctdb_init(struct event_context *ev)
2273 struct ctdb_context *ctdb;
2275 ctdb = talloc_zero(ev, struct ctdb_context);
2277 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
2281 ctdb->idr = idr_init(ctdb);
2282 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
2284 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
2286 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
2298 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
2300 ctdb->flags |= flags;
2305 return the pnn of this node
2307 uint32_t ctdb_get_pnn(struct ctdb_context *ctdb)
2314 get the uptime of a remote node
2316 struct ctdb_client_control_state *
2317 ctdb_ctrl_uptime_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
2319 return ctdb_control_send(ctdb, destnode, 0,
2320 CTDB_CONTROL_UPTIME, 0, tdb_null,
2321 mem_ctx, &timeout, NULL);
2324 int ctdb_ctrl_uptime_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, struct ctdb_uptime **uptime)
2330 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
2331 if (ret != 0 || res != 0) {
2332 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_uptime_recv failed\n"));
2336 *uptime = (struct ctdb_uptime *)talloc_steal(mem_ctx, outdata.dptr);
2341 int ctdb_ctrl_uptime(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, struct ctdb_uptime **uptime)
2343 struct ctdb_client_control_state *state;
2345 state = ctdb_ctrl_uptime_send(ctdb, mem_ctx, timeout, destnode);
2346 return ctdb_ctrl_uptime_recv(ctdb, mem_ctx, state, uptime);
2350 send a control to execute the "recovered" event script on a node
2352 int ctdb_ctrl_end_recovery(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
2357 ret = ctdb_control(ctdb, destnode, 0,
2358 CTDB_CONTROL_END_RECOVERY, 0, tdb_null,
2359 NULL, NULL, &status, &timeout, NULL);
2360 if (ret != 0 || status != 0) {
2361 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for end_recovery failed\n"));
2369 callback for the async helpers used when sending the same control
2370 to multiple nodes in parallell.
2372 static void async_callback(struct ctdb_client_control_state *state)
2374 struct client_async_data *data = talloc_get_type(state->async.private_data, struct client_async_data);
2375 struct ctdb_context *ctdb = talloc_get_type(state->ctdb, struct ctdb_context);
2379 uint32_t destnode = state->c->hdr.destnode;
2381 /* one more node has responded with recmode data */
2384 /* if we failed to push the db, then return an error and let
2385 the main loop try again.
2387 if (state->state != CTDB_CONTROL_DONE) {
2388 if ( !data->dont_log_errors) {
2389 DEBUG(DEBUG_ERR,("Async operation failed with state %d, opcode:%u\n", state->state, data->opcode));
2392 if (data->fail_callback) {
2393 data->fail_callback(ctdb, destnode, res, outdata,
2394 data->callback_data);
2399 state->async.fn = NULL;
2401 ret = ctdb_control_recv(ctdb, state, data, &outdata, &res, NULL);
2402 if ((ret != 0) || (res != 0)) {
2403 if ( !data->dont_log_errors) {
2404 DEBUG(DEBUG_ERR,("Async operation failed with ret=%d res=%d opcode=%u\n", ret, (int)res, data->opcode));
2407 if (data->fail_callback) {
2408 data->fail_callback(ctdb, destnode, res, outdata,
2409 data->callback_data);
2412 if ((ret == 0) && (data->callback != NULL)) {
2413 data->callback(ctdb, destnode, res, outdata,
2414 data->callback_data);
2419 void ctdb_client_async_add(struct client_async_data *data, struct ctdb_client_control_state *state)
2421 /* set up the callback functions */
2422 state->async.fn = async_callback;
2423 state->async.private_data = data;
2425 /* one more control to wait for to complete */
2430 /* wait for up to the maximum number of seconds allowed
2431 or until all nodes we expect a response from has replied
2433 int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *data)
2435 while (data->count > 0) {
2436 event_loop_once(ctdb->ev);
2438 if (data->fail_count != 0) {
2439 if (!data->dont_log_errors) {
2440 DEBUG(DEBUG_ERR,("Async wait failed - fail_count=%u\n",
2450 perform a simple control on the listed nodes
2451 The control cannot return data
2453 int ctdb_client_async_control(struct ctdb_context *ctdb,
2454 enum ctdb_controls opcode,
2457 struct timeval timeout,
2458 bool dont_log_errors,
2460 client_async_callback client_callback,
2461 client_async_callback fail_callback,
2462 void *callback_data)
2464 struct client_async_data *async_data;
2465 struct ctdb_client_control_state *state;
2468 async_data = talloc_zero(ctdb, struct client_async_data);
2469 CTDB_NO_MEMORY_FATAL(ctdb, async_data);
2470 async_data->dont_log_errors = dont_log_errors;
2471 async_data->callback = client_callback;
2472 async_data->fail_callback = fail_callback;
2473 async_data->callback_data = callback_data;
2474 async_data->opcode = opcode;
2476 num_nodes = talloc_get_size(nodes) / sizeof(uint32_t);
2478 /* loop over all nodes and send an async control to each of them */
2479 for (j=0; j<num_nodes; j++) {
2480 uint32_t pnn = nodes[j];
2482 state = ctdb_control_send(ctdb, pnn, srvid, opcode,
2483 0, data, async_data, &timeout, NULL);
2484 if (state == NULL) {
2485 DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
2486 talloc_free(async_data);
2490 ctdb_client_async_add(async_data, state);
2493 if (ctdb_client_async_wait(ctdb, async_data) != 0) {
2494 talloc_free(async_data);
2498 talloc_free(async_data);
2502 uint32_t *list_of_vnnmap_nodes(struct ctdb_context *ctdb,
2503 struct ctdb_vnn_map *vnn_map,
2504 TALLOC_CTX *mem_ctx,
2507 int i, j, num_nodes;
2510 for (i=num_nodes=0;i<vnn_map->size;i++) {
2511 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2517 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2518 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2520 for (i=j=0;i<vnn_map->size;i++) {
2521 if (vnn_map->map[i] == ctdb->pnn && !include_self) {
2524 nodes[j++] = vnn_map->map[i];
2530 uint32_t *list_of_active_nodes(struct ctdb_context *ctdb,
2531 struct ctdb_node_map *node_map,
2532 TALLOC_CTX *mem_ctx,
2535 int i, j, num_nodes;
2538 for (i=num_nodes=0;i<node_map->num;i++) {
2539 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2542 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2548 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2549 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2551 for (i=j=0;i<node_map->num;i++) {
2552 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2555 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2558 nodes[j++] = node_map->nodes[i].pnn;
2564 uint32_t *list_of_active_nodes_except_pnn(struct ctdb_context *ctdb,
2565 struct ctdb_node_map *node_map,
2566 TALLOC_CTX *mem_ctx,
2569 int i, j, num_nodes;
2572 for (i=num_nodes=0;i<node_map->num;i++) {
2573 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2576 if (node_map->nodes[i].pnn == pnn) {
2582 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2583 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2585 for (i=j=0;i<node_map->num;i++) {
2586 if (node_map->nodes[i].flags & NODE_FLAGS_INACTIVE) {
2589 if (node_map->nodes[i].pnn == pnn) {
2592 nodes[j++] = node_map->nodes[i].pnn;
2598 uint32_t *list_of_connected_nodes(struct ctdb_context *ctdb,
2599 struct ctdb_node_map *node_map,
2600 TALLOC_CTX *mem_ctx,
2603 int i, j, num_nodes;
2606 for (i=num_nodes=0;i<node_map->num;i++) {
2607 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
2610 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2616 nodes = talloc_array(mem_ctx, uint32_t, num_nodes);
2617 CTDB_NO_MEMORY_FATAL(ctdb, nodes);
2619 for (i=j=0;i<node_map->num;i++) {
2620 if (node_map->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
2623 if (node_map->nodes[i].pnn == ctdb->pnn && !include_self) {
2626 nodes[j++] = node_map->nodes[i].pnn;
2633 this is used to test if a pnn lock exists and if it exists will return
2634 the number of connections that pnn has reported or -1 if that recovery
2635 daemon is not running.
2638 ctdb_read_pnn_lock(int fd, int32_t pnn)
2643 lock.l_type = F_WRLCK;
2644 lock.l_whence = SEEK_SET;
2649 if (fcntl(fd, F_GETLK, &lock) != 0) {
2650 DEBUG(DEBUG_ERR, (__location__ " F_GETLK failed with %s\n", strerror(errno)));
2654 if (lock.l_type == F_UNLCK) {
2658 if (pread(fd, &c, 1, pnn) == -1) {
2659 DEBUG(DEBUG_CRIT,(__location__ " failed read pnn count - %s\n", strerror(errno)));
2667 get capabilities of a remote node
2669 struct ctdb_client_control_state *
2670 ctdb_ctrl_getcapabilities_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
2672 return ctdb_control_send(ctdb, destnode, 0,
2673 CTDB_CONTROL_GET_CAPABILITIES, 0, tdb_null,
2674 mem_ctx, &timeout, NULL);
2677 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities)
2683 ret = ctdb_control_recv(ctdb, state, mem_ctx, &outdata, &res, NULL);
2684 if ( (ret != 0) || (res != 0) ) {
2685 DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getcapabilities_recv failed\n"));
2690 *capabilities = *((uint32_t *)outdata.dptr);
2696 int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities)
2698 struct ctdb_client_control_state *state;
2699 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
2702 state = ctdb_ctrl_getcapabilities_send(ctdb, tmp_ctx, timeout, destnode);
2703 ret = ctdb_ctrl_getcapabilities_recv(ctdb, tmp_ctx, state, capabilities);
2704 talloc_free(tmp_ctx);
2709 * check whether a transaction is active on a given db on a given node
2711 int32_t ctdb_ctrl_transaction_active(struct ctdb_context *ctdb,
2719 indata.dptr = (uint8_t *)&db_id;
2720 indata.dsize = sizeof(db_id);
2722 ret = ctdb_control(ctdb, destnode, 0,
2723 CTDB_CONTROL_TRANS2_ACTIVE,
2724 0, indata, NULL, NULL, &status,
2728 DEBUG(DEBUG_ERR, (__location__ " ctdb control for transaction_active failed\n"));
2736 struct ctdb_transaction_handle {
2737 struct ctdb_db_context *ctdb_db;
2740 * we store the reads and writes done under a transaction:
2741 * - one list stores both reads and writes (m_all),
2742 * - the other just writes (m_write)
2744 struct ctdb_marshall_buffer *m_all;
2745 struct ctdb_marshall_buffer *m_write;
2748 /* start a transaction on a database */
2749 static int ctdb_transaction_destructor(struct ctdb_transaction_handle *h)
2751 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
2755 /* start a transaction on a database */
2756 static int ctdb_transaction_fetch_start(struct ctdb_transaction_handle *h)
2758 struct ctdb_record_handle *rh;
2761 struct ctdb_ltdb_header header;
2762 TALLOC_CTX *tmp_ctx;
2763 const char *keyname = CTDB_TRANSACTION_LOCK_KEY;
2765 struct ctdb_db_context *ctdb_db = h->ctdb_db;
2769 key.dptr = discard_const(keyname);
2770 key.dsize = strlen(keyname);
2772 if (!ctdb_db->persistent) {
2773 DEBUG(DEBUG_ERR,(__location__ " Attempted transaction on non-persistent database\n"));
2778 tmp_ctx = talloc_new(h);
2780 rh = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, NULL);
2782 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch_lock database\n"));
2783 talloc_free(tmp_ctx);
2787 status = ctdb_ctrl_transaction_active(ctdb_db->ctdb,
2791 unsigned long int usec = (1000 + random()) % 100000;
2792 DEBUG(DEBUG_DEBUG, (__location__ " transaction is active "
2793 "on db_id[0x%08x]. waiting for %lu "
2795 ctdb_db->db_id, usec));
2796 talloc_free(tmp_ctx);
2802 * store the pid in the database:
2803 * it is not enough that the node is dmaster...
2806 data.dptr = (unsigned char *)&pid;
2807 data.dsize = sizeof(pid_t);
2809 rh->header.dmaster = ctdb_db->ctdb->pnn;
2810 ret = ctdb_ltdb_store(ctdb_db, key, &(rh->header), data);
2812 DEBUG(DEBUG_ERR, (__location__ " Failed to store pid in "
2813 "transaction record\n"));
2814 talloc_free(tmp_ctx);
2820 ret = tdb_transaction_start(ctdb_db->ltdb->tdb);
2822 DEBUG(DEBUG_ERR,(__location__ " Failed to start tdb transaction\n"));
2823 talloc_free(tmp_ctx);
2827 ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, &data);
2829 DEBUG(DEBUG_ERR,(__location__ " Failed to re-fetch transaction "
2830 "lock record inside transaction\n"));
2831 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2832 talloc_free(tmp_ctx);
2836 if (header.dmaster != ctdb_db->ctdb->pnn) {
2837 DEBUG(DEBUG_DEBUG,(__location__ " not dmaster any more on "
2838 "transaction lock record\n"));
2839 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2840 talloc_free(tmp_ctx);
2844 if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
2845 DEBUG(DEBUG_DEBUG, (__location__ " my pid is not stored in "
2846 "the transaction lock record\n"));
2847 tdb_transaction_cancel(ctdb_db->ltdb->tdb);
2848 talloc_free(tmp_ctx);
2852 talloc_free(tmp_ctx);
2858 /* start a transaction on a database */
2859 struct ctdb_transaction_handle *ctdb_transaction_start(struct ctdb_db_context *ctdb_db,
2860 TALLOC_CTX *mem_ctx)
2862 struct ctdb_transaction_handle *h;
2865 h = talloc_zero(mem_ctx, struct ctdb_transaction_handle);
2867 DEBUG(DEBUG_ERR,(__location__ " oom for transaction handle\n"));
2871 h->ctdb_db = ctdb_db;
2873 ret = ctdb_transaction_fetch_start(h);
2879 talloc_set_destructor(h, ctdb_transaction_destructor);
2887 fetch a record inside a transaction
2889 int ctdb_transaction_fetch(struct ctdb_transaction_handle *h,
2890 TALLOC_CTX *mem_ctx,
2891 TDB_DATA key, TDB_DATA *data)
2893 struct ctdb_ltdb_header header;
2896 ZERO_STRUCT(header);
2898 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, mem_ctx, data);
2899 if (ret == -1 && header.dmaster == (uint32_t)-1) {
2900 /* record doesn't exist yet */
2909 if (!h->in_replay) {
2910 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 1, key, NULL, *data);
2911 if (h->m_all == NULL) {
2912 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
2921 stores a record inside a transaction
2923 int ctdb_transaction_store(struct ctdb_transaction_handle *h,
2924 TDB_DATA key, TDB_DATA data)
2926 TALLOC_CTX *tmp_ctx = talloc_new(h);
2927 struct ctdb_ltdb_header header;
2931 ZERO_STRUCT(header);
2933 /* we need the header so we can update the RSN */
2934 ret = ctdb_ltdb_fetch(h->ctdb_db, key, &header, tmp_ctx, &olddata);
2935 if (ret == -1 && header.dmaster == (uint32_t)-1) {
2936 /* the record doesn't exist - create one with us as dmaster.
2937 This is only safe because we are in a transaction and this
2938 is a persistent database */
2939 ZERO_STRUCT(header);
2940 } else if (ret != 0) {
2941 DEBUG(DEBUG_ERR,(__location__ " Failed to fetch record\n"));
2942 talloc_free(tmp_ctx);
2946 if (data.dsize == olddata.dsize &&
2947 memcmp(data.dptr, olddata.dptr, data.dsize) == 0) {
2948 /* save writing the same data */
2949 talloc_free(tmp_ctx);
2953 header.dmaster = h->ctdb_db->ctdb->pnn;
2956 if (!h->in_replay) {
2957 h->m_all = ctdb_marshall_add(h, h->m_all, h->ctdb_db->db_id, 0, key, NULL, data);
2958 if (h->m_all == NULL) {
2959 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
2960 talloc_free(tmp_ctx);
2965 h->m_write = ctdb_marshall_add(h, h->m_write, h->ctdb_db->db_id, 0, key, &header, data);
2966 if (h->m_write == NULL) {
2967 DEBUG(DEBUG_ERR,(__location__ " Failed to add to marshalling record\n"));
2968 talloc_free(tmp_ctx);
2972 ret = ctdb_ltdb_store(h->ctdb_db, key, &header, data);
2974 talloc_free(tmp_ctx);
2980 replay a transaction
2982 static int ctdb_replay_transaction(struct ctdb_transaction_handle *h)
2985 struct ctdb_rec_data *rec = NULL;
2987 h->in_replay = true;
2988 talloc_free(h->m_write);
2991 ret = ctdb_transaction_fetch_start(h);
2996 for (i=0;i<h->m_all->count;i++) {
2999 rec = ctdb_marshall_loop_next(h->m_all, rec, NULL, NULL, &key, &data);
3001 DEBUG(DEBUG_ERR, (__location__ " Out of records in ctdb_replay_transaction?\n"));
3005 if (rec->reqid == 0) {
3007 if (ctdb_transaction_store(h, key, data) != 0) {
3012 TALLOC_CTX *tmp_ctx = talloc_new(h);
3014 if (ctdb_transaction_fetch(h, tmp_ctx, key, &data2) != 0) {
3015 talloc_free(tmp_ctx);
3018 if (data2.dsize != data.dsize ||
3019 memcmp(data2.dptr, data.dptr, data.dsize) != 0) {
3020 /* the record has changed on us - we have to give up */
3021 talloc_free(tmp_ctx);
3024 talloc_free(tmp_ctx);
3031 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3037 commit a transaction
3039 int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
3043 struct ctdb_context *ctdb = h->ctdb_db->ctdb;
3044 struct timeval timeout;
3045 enum ctdb_controls failure_control = CTDB_CONTROL_TRANS2_ERROR;
3047 talloc_set_destructor(h, NULL);
3049 /* our commit strategy is quite complex.
3051 - we first try to commit the changes to all other nodes
3053 - if that works, then we commit locally and we are done
3055 - if a commit on another node fails, then we need to cancel
3056 the transaction, then restart the transaction (thus
3057 opening a window of time for a pending recovery to
3058 complete), then replay the transaction, checking all the
3059 reads and writes (checking that reads give the same data,
3060 and writes succeed). Then we retry the transaction to the
3065 if (h->m_write == NULL) {
3066 /* no changes were made */
3067 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3072 /* tell ctdbd to commit to the other nodes */
3073 timeout = timeval_current_ofs(1, 0);
3074 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3075 retries==0?CTDB_CONTROL_TRANS2_COMMIT:CTDB_CONTROL_TRANS2_COMMIT_RETRY, 0,
3076 ctdb_marshall_finish(h->m_write), NULL, NULL, &status,
3078 if (ret != 0 || status != 0) {
3079 tdb_transaction_cancel(h->ctdb_db->ltdb->tdb);
3080 DEBUG(DEBUG_NOTICE, (__location__ " transaction commit%s failed"
3081 ", retrying after 1 second...\n",
3082 (retries==0)?"":"retry "));
3086 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3088 /* work out what error code we will give if we
3089 have to fail the operation */
3090 switch ((enum ctdb_trans2_commit_error)status) {
3091 case CTDB_TRANS2_COMMIT_SUCCESS:
3092 case CTDB_TRANS2_COMMIT_SOMEFAIL:
3093 case CTDB_TRANS2_COMMIT_TIMEOUT:
3094 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3096 case CTDB_TRANS2_COMMIT_ALLFAIL:
3097 failure_control = CTDB_CONTROL_TRANS2_FINISHED;
3102 if (++retries == 100) {
3103 DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n",
3104 h->ctdb_db->db_id, retries, (unsigned)failure_control));
3105 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3106 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3107 tdb_null, NULL, NULL, NULL, NULL, NULL);
3112 if (ctdb_replay_transaction(h) != 0) {
3113 DEBUG(DEBUG_ERR, (__location__ " Failed to replay "
3114 "transaction on db 0x%08x, "
3115 "failure control =%u\n",
3117 (unsigned)failure_control));
3118 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3119 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3120 tdb_null, NULL, NULL, NULL, NULL, NULL);
3126 failure_control = CTDB_CONTROL_TRANS2_ERROR;
3129 /* do the real commit locally */
3130 ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
3132 DEBUG(DEBUG_ERR, (__location__ " Failed to commit transaction "
3133 "on db id 0x%08x locally, "
3134 "failure_control=%u\n",
3136 (unsigned)failure_control));
3137 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3138 failure_control, CTDB_CTRL_FLAG_NOREPLY,
3139 tdb_null, NULL, NULL, NULL, NULL, NULL);
3144 /* tell ctdbd that we are finished with our local commit */
3145 ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id,
3146 CTDB_CONTROL_TRANS2_FINISHED, CTDB_CTRL_FLAG_NOREPLY,
3147 tdb_null, NULL, NULL, NULL, NULL, NULL);
3153 recovery daemon ping to main daemon
3155 int ctdb_ctrl_recd_ping(struct ctdb_context *ctdb)
3160 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_PING, 0, tdb_null,
3161 ctdb, NULL, &res, NULL, NULL);
3162 if (ret != 0 || res != 0) {
3163 DEBUG(DEBUG_ERR,("Failed to send recd ping\n"));
3170 /* when forking the main daemon and the child process needs to connect back
3171 * to the daemon as a client process, this function can be used to change
3172 * the ctdb context from daemon into client mode
3174 int switch_from_server_to_client(struct ctdb_context *ctdb)
3178 /* shutdown the transport */
3179 if (ctdb->methods) {
3180 ctdb->methods->shutdown(ctdb);
3183 /* get a new event context */
3184 talloc_free(ctdb->ev);
3185 ctdb->ev = event_context_init(ctdb);
3187 close(ctdb->daemon.sd);
3188 ctdb->daemon.sd = -1;
3190 /* initialise ctdb */
3191 ret = ctdb_socket_connect(ctdb);
3193 DEBUG(DEBUG_ALERT, (__location__ " Failed to init ctdb client\n"));
3201 get the status of running the monitor eventscripts: NULL means never run.
3203 int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
3204 struct timeval timeout, uint32_t destnode,
3205 TALLOC_CTX *mem_ctx, enum ctdb_eventscript_call type,
3206 struct ctdb_scripts_wire **script_status)
3209 TDB_DATA outdata, indata;
3211 uint32_t uinttype = type;
3213 indata.dptr = (uint8_t *)&uinttype;
3214 indata.dsize = sizeof(uinttype);
3216 ret = ctdb_control(ctdb, destnode, 0,
3217 CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS, 0, indata,
3218 mem_ctx, &outdata, &res, &timeout, NULL);
3219 if (ret != 0 || res != 0) {
3220 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getscriptstatus failed ret:%d res:%d\n", ret, res));
3224 if (outdata.dsize == 0) {
3225 *script_status = NULL;
3227 *script_status = (struct ctdb_scripts_wire *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
3228 talloc_free(outdata.dptr);
3235 tell the main daemon how long it took to lock the reclock file
3237 int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval timeout, double latency)
3243 data.dptr = (uint8_t *)&latency;
3244 data.dsize = sizeof(latency);
3246 ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_RECD_RECLOCK_LATENCY, 0, data,
3247 ctdb, NULL, &res, NULL, NULL);
3248 if (ret != 0 || res != 0) {
3249 DEBUG(DEBUG_ERR,("Failed to send recd reclock latency\n"));
3257 get the name of the reclock file
3259 int ctdb_ctrl_getreclock(struct ctdb_context *ctdb, struct timeval timeout,
3260 uint32_t destnode, TALLOC_CTX *mem_ctx,
3267 ret = ctdb_control(ctdb, destnode, 0,
3268 CTDB_CONTROL_GET_RECLOCK_FILE, 0, tdb_null,
3269 mem_ctx, &data, &res, &timeout, NULL);
3270 if (ret != 0 || res != 0) {
3274 if (data.dsize == 0) {
3277 *name = talloc_strdup(mem_ctx, discard_const(data.dptr));
3279 talloc_free(data.dptr);
3285 set the reclock filename for a node
3287 int ctdb_ctrl_setreclock(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *reclock)
3293 if (reclock == NULL) {
3297 data.dsize = strlen(reclock) + 1;
3298 data.dptr = discard_const(reclock);
3301 ret = ctdb_control(ctdb, destnode, 0,
3302 CTDB_CONTROL_SET_RECLOCK_FILE, 0, data,
3303 NULL, NULL, &res, &timeout, NULL);
3304 if (ret != 0 || res != 0) {
3305 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setreclock failed\n"));
3315 int ctdb_ctrl_stop_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3320 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_STOP_NODE, 0, tdb_null,
3321 ctdb, NULL, &res, &timeout, NULL);
3322 if (ret != 0 || res != 0) {
3323 DEBUG(DEBUG_ERR,("Failed to stop node\n"));
3333 int ctdb_ctrl_continue_node(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
3337 ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_CONTINUE_NODE, 0, tdb_null,
3338 ctdb, NULL, NULL, &timeout, NULL);
3340 DEBUG(DEBUG_ERR,("Failed to continue node\n"));
3348 set the natgw state for a node
3350 int ctdb_ctrl_setnatgwstate(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t natgwstate)
3356 data.dsize = sizeof(natgwstate);
3357 data.dptr = (uint8_t *)&natgwstate;
3359 ret = ctdb_control(ctdb, destnode, 0,
3360 CTDB_CONTROL_SET_NATGWSTATE, 0, data,
3361 NULL, NULL, &res, &timeout, NULL);
3362 if (ret != 0 || res != 0) {
3363 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setnatgwstate failed\n"));
3371 set the lmaster role for a node
3373 int ctdb_ctrl_setlmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t lmasterrole)
3379 data.dsize = sizeof(lmasterrole);
3380 data.dptr = (uint8_t *)&lmasterrole;
3382 ret = ctdb_control(ctdb, destnode, 0,
3383 CTDB_CONTROL_SET_LMASTERROLE, 0, data,
3384 NULL, NULL, &res, &timeout, NULL);
3385 if (ret != 0 || res != 0) {
3386 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setlmasterrole failed\n"));
3394 set the recmaster role for a node
3396 int ctdb_ctrl_setrecmasterrole(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmasterrole)
3402 data.dsize = sizeof(recmasterrole);
3403 data.dptr = (uint8_t *)&recmasterrole;
3405 ret = ctdb_control(ctdb, destnode, 0,
3406 CTDB_CONTROL_SET_RECMASTERROLE, 0, data,
3407 NULL, NULL, &res, &timeout, NULL);
3408 if (ret != 0 || res != 0) {
3409 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmasterrole failed\n"));
3416 /* enable an eventscript
3418 int ctdb_ctrl_enablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
3424 data.dsize = strlen(script) + 1;
3425 data.dptr = discard_const(script);
3427 ret = ctdb_control(ctdb, destnode, 0,
3428 CTDB_CONTROL_ENABLE_SCRIPT, 0, data,
3429 NULL, NULL, &res, &timeout, NULL);
3430 if (ret != 0 || res != 0) {
3431 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enablescript failed\n"));
3438 /* disable an eventscript
3440 int ctdb_ctrl_disablescript(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, const char *script)
3446 data.dsize = strlen(script) + 1;
3447 data.dptr = discard_const(script);
3449 ret = ctdb_control(ctdb, destnode, 0,
3450 CTDB_CONTROL_DISABLE_SCRIPT, 0, data,
3451 NULL, NULL, &res, &timeout, NULL);
3452 if (ret != 0 || res != 0) {
3453 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disablescript failed\n"));
3461 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime)
3467 data.dsize = sizeof(*bantime);
3468 data.dptr = (uint8_t *)bantime;
3470 ret = ctdb_control(ctdb, destnode, 0,
3471 CTDB_CONTROL_SET_BAN_STATE, 0, data,
3472 NULL, NULL, &res, &timeout, NULL);
3473 if (ret != 0 || res != 0) {
3474 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
3482 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime)
3487 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3489 ret = ctdb_control(ctdb, destnode, 0,
3490 CTDB_CONTROL_GET_BAN_STATE, 0, tdb_null,
3491 tmp_ctx, &outdata, &res, &timeout, NULL);
3492 if (ret != 0 || res != 0) {
3493 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set ban state failed\n"));
3494 talloc_free(tmp_ctx);
3498 *bantime = (struct ctdb_ban_time *)talloc_steal(mem_ctx, outdata.dptr);
3499 talloc_free(tmp_ctx);
3505 int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
3510 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3512 data.dptr = (uint8_t*)db_prio;
3513 data.dsize = sizeof(*db_prio);
3515 ret = ctdb_control(ctdb, destnode, 0,
3516 CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
3517 tmp_ctx, NULL, &res, &timeout, NULL);
3518 if (ret != 0 || res != 0) {
3519 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
3520 talloc_free(tmp_ctx);
3524 talloc_free(tmp_ctx);
3529 int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
3534 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
3536 data.dptr = (uint8_t*)&db_id;
3537 data.dsize = sizeof(db_id);
3539 ret = ctdb_control(ctdb, destnode, 0,
3540 CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
3541 tmp_ctx, NULL, &res, &timeout, NULL);
3542 if (ret != 0 || res < 0) {
3543 DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
3544 talloc_free(tmp_ctx);
3552 talloc_free(tmp_ctx);