3 Utility functions to connect to the ctdb daemon
5 Copyright (C) Andrew Tridgell 2006
6 Copyright (C) Ronnie sahlberg 2010
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
25 #include "lib/tdb/include/tdb.h"
26 #include "lib/util/dlinklist.h"
27 #include "lib/events/events.h"
28 #include "lib/events/events_internal.h"
29 #include "lib/tdb/include/tdb.h"
30 #include "include/ctdb.h"
31 #include "include/ctdb_protocol.h"
32 #include "include/ctdb_private.h"
34 #include "system/filesys.h"
38 this is the dummy null procedure that all databases support
40 static int ctdb_null_func(struct ctdb_call_info *call)
46 this is a plain fetch procedure that all databases support
48 static int ctdb_fetch_func(struct ctdb_call_info *call)
50 call->reply_data = &call->record_data;
56 struct ctdb_context *ctdb_connect(const char *addr)
58 struct event_context *ev;
59 struct ctdb_context *ctdb;
62 ev = event_context_init(NULL);
67 fprintf(stderr, "Failed to init ctdb\n");
71 ret = ctdb_set_socketname(ctdb, addr);
73 fprintf(stderr, __location__ " ctdb_set_socketname failed - %s\n", ctdb_errstr(ctdb));
78 ret = ctdb_socket_connect(ctdb);
80 fprintf(stderr, __location__ " Failed to connect to daemon\n");
89 int ctdb_get_fd(struct ctdb_context *ctdb)
91 return ctdb->daemon.sd;
94 int ctdb_which_events(struct ctdb_context *ctdb)
96 if (ctdb_queue_length(ctdb->daemon.queue) > 0) {
97 return POLLIN|POLLOUT;
106 initialise the ctdb daemon for client applications
108 struct ctdb_context *ctdb_init(struct event_context *ev)
111 struct ctdb_context *ctdb;
113 ctdb = talloc_zero(ev, struct ctdb_context);
115 DEBUG(DEBUG_ERR,(__location__ " talloc_zero failed.\n"));
119 ctdb->idr = idr_init(ctdb);
120 CTDB_NO_MEMORY_NULL(ctdb, ctdb->idr);
122 ret = ctdb_set_socketname(ctdb, CTDB_PATH);
124 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_socketname failed.\n"));
137 * This is a bit hairy. due to the way ctdbd uses events.
138 * ctdbd quite frequently uses
139 * event_add_timed(... timeval_zero() ...)
141 * for example once it has finished reading off a full pdu off the
142 * domain socket, before calling the actual recdeive function.
144 * we probably need a new event function to handle these timed events
145 * event_loop_all_queued() or similar
147 int ctdb_service(struct ctdb_context *ctdb)
152 ret = event_loop_once(ctdb->ev);
154 t = common_event_loop_timer_delay(ctdb->ev);
155 } while(timeval_is_zero(&t));
162 int ctdb_free(ctdb_handle *handle)
168 struct ctdb_control_cb_data {
177 /*************************
178 * GET PNN of local node *
179 *************************/
181 ctdb_getpnn_recv_cb(struct ctdb_client_control_state *state)
183 struct ctdb_control_cb_data *cb_data = state->async.private_data;
184 ctdb_getpnn_cb callback = (ctdb_getpnn_cb)cb_data->callback;
186 if (state->state != CTDB_CONTROL_DONE) {
187 DEBUG(DEBUG_ERR, (__location__ " ctdb_getpnn_recv_cb failed with state:%d\n", state->state));
188 callback(-1, 0, cb_data->private_data);
192 callback(0, state->status, cb_data->private_data);
196 ctdb_getpnn_send(struct ctdb_context *ctdb,
198 ctdb_getpnn_cb callback,
201 struct ctdb_client_control_state *state;
202 struct ctdb_control_cb_data *cb_data;
204 state = ctdb_control_send(ctdb, destnode, 0,
205 CTDB_CONTROL_GET_PNN, 0, tdb_null,
209 DEBUG(DEBUG_ERR,(__location__ " Failed to send GET_PNN control\n"));
213 if (callback != NULL) {
214 cb_data = talloc(state, struct ctdb_control_cb_data);
215 cb_data->callback = callback;
216 cb_data->private_data = private_data;
218 state->async.fn = ctdb_getpnn_recv_cb;
219 state->async.private_data = cb_data;
222 return (ctdb_handle *)state;
225 int ctdb_getpnn_recv(struct ctdb_context *ctdb, ctdb_handle *handle, uint32_t *pnn)
227 struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
231 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
233 DEBUG(DEBUG_ERR,(__location__ " ctdb_getpnn_recv failed\n"));
238 *pnn = (uint32_t)res;
244 int ctdb_getpnn(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *pnn)
246 struct ctdb_client_control_state *state;
248 state = ctdb_getpnn_send(ctdb, destnode, NULL, NULL);
250 DEBUG(DEBUG_ERR,(__location__ " ctdb_getpnn_send() failed.\n"));
254 return ctdb_getpnn_recv(ctdb, state, pnn);
259 /***********************
260 * GET RECOVERY MASTER *
261 ***********************/
263 ctdb_getrecmaster_recv_cb(struct ctdb_client_control_state *state)
265 struct ctdb_control_cb_data *cb_data = state->async.private_data;
266 ctdb_getrecmaster_cb callback = (ctdb_getrecmaster_cb)cb_data->callback;
268 if (state->state != CTDB_CONTROL_DONE) {
269 DEBUG(DEBUG_ERR, (__location__ " ctdb_getrecmaster_recv_cb failed with state:%d\n", state->state));
270 callback(-1, 0, cb_data->private_data);
274 callback(0, state->status, cb_data->private_data);
278 ctdb_getrecmaster_send(struct ctdb_context *ctdb,
280 ctdb_getrecmaster_cb callback,
283 struct ctdb_client_control_state *state;
284 struct ctdb_control_cb_data *cb_data;
286 state = ctdb_control_send(ctdb, destnode, 0,
287 CTDB_CONTROL_GET_RECMASTER, 0, tdb_null,
291 DEBUG(DEBUG_ERR,(__location__ " Failed to send GET_RECMASTER control\n"));
295 if (callback != NULL) {
296 cb_data = talloc(state, struct ctdb_control_cb_data);
297 cb_data->callback = callback;
298 cb_data->private_data = private_data;
300 state->async.fn = ctdb_getrecmaster_recv_cb;
301 state->async.private_data = cb_data;
304 return (ctdb_handle *)state;
307 int ctdb_getrecmaster_recv(struct ctdb_context *ctdb, ctdb_handle *handle, uint32_t *recmaster)
309 struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
313 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
315 DEBUG(DEBUG_ERR,(__location__ " ctdb_getrecmaster_recv failed\n"));
319 if (recmaster != NULL) {
320 *recmaster = (uint32_t)res;
326 int ctdb_getrecmaster(struct ctdb_context *ctdb, uint32_t destnode, uint32_t *recmaster)
328 struct ctdb_client_control_state *state;
330 state = ctdb_getrecmaster_send(ctdb, destnode, NULL, NULL);
332 DEBUG(DEBUG_ERR,(__location__ " ctdb_getrecmaster_send() failed.\n"));
336 return ctdb_getrecmaster_recv(ctdb, state, recmaster);
343 ctdb_set_message_handler_recv_cb(struct ctdb_client_control_state *state)
345 struct ctdb_control_cb_data *cb_data = state->async.private_data;
346 ctdb_set_message_handler_cb callback = (ctdb_set_message_handler_cb)cb_data->callback;
348 if (state->state != CTDB_CONTROL_DONE) {
349 DEBUG(DEBUG_ERR, (__location__ " ctdb_getrecmaster_recv_cb failed with state:%d\n", state->state));
350 callback(-1, cb_data->private_data);
354 callback(state->status, cb_data->private_data);
359 tell the daemon what messaging srvid we will use, and register the message
360 handler function in the client
363 ctdb_set_message_handler_send(struct ctdb_context *ctdb, uint64_t srvid,
364 ctdb_set_message_handler_cb callback,
365 ctdb_message_fn_t handler,
369 struct ctdb_client_control_state *state;
370 struct ctdb_control_cb_data *cb_data;
372 if (ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data) != 0) {
376 state = ctdb_control_send(ctdb, CTDB_CURRENT_NODE, srvid,
377 CTDB_CONTROL_REGISTER_SRVID, 0, tdb_null,
381 DEBUG(DEBUG_ERR,(__location__ " Failed to send REGISTER_SRVID control\n"));
385 if (callback != NULL) {
386 cb_data = talloc(state, struct ctdb_control_cb_data);
387 cb_data->callback = callback;
388 cb_data->private_data = private_data;
390 state->async.fn = ctdb_set_message_handler_recv_cb;
391 state->async.private_data = cb_data;
394 return (ctdb_handle *)state;
397 int ctdb_set_message_handler_recv(struct ctdb_context *ctdb, ctdb_handle *handle)
399 struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
403 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
404 if (ret != 0 || res != 0) {
405 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_message_handler_recv failed\n"));
409 return state->status;
412 int ctdb_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid, ctdb_message_fn_t handler, void *private_data)
414 struct ctdb_client_control_state *state;
416 state = ctdb_set_message_handler_send(ctdb, srvid, NULL, handler, private_data);
418 DEBUG(DEBUG_ERR,(__location__ " ctdb_set_message_handler_send() failed.\n"));
422 return ctdb_set_message_handler_recv(ctdb, state);
428 ctdb_remove_message_handler_recv_cb(struct ctdb_client_control_state *state)
430 struct ctdb_control_cb_data *cb_data = state->async.private_data;
431 ctdb_remove_message_handler_cb callback = (ctdb_remove_message_handler_cb)cb_data->callback;
433 if (state->state != CTDB_CONTROL_DONE) {
434 DEBUG(DEBUG_ERR, (__location__ " ctdb_getrecmaster_recv_cb failed with state:%d\n", state->state));
435 callback(-1, cb_data->private_data);
439 callback(state->status, cb_data->private_data);
444 ctdb_remove_message_handler_send(struct ctdb_context *ctdb, uint64_t srvid,
445 ctdb_remove_message_handler_cb callback,
449 struct ctdb_client_control_state *state;
450 struct ctdb_control_cb_data *cb_data;
452 if (ctdb_deregister_message_handler(ctdb, srvid, private_data)) {
456 state = ctdb_control_send(ctdb, CTDB_CURRENT_NODE, srvid,
457 CTDB_CONTROL_DEREGISTER_SRVID, 0, tdb_null,
461 DEBUG(DEBUG_ERR,(__location__ " Failed to send DEREGISTER_SRVID control\n"));
465 if (callback != NULL) {
466 cb_data = talloc(state, struct ctdb_control_cb_data);
467 cb_data->callback = callback;
468 cb_data->private_data = private_data;
470 state->async.fn = ctdb_remove_message_handler_recv_cb;
471 state->async.private_data = cb_data;
474 return (ctdb_handle *)state;
478 int ctdb_remove_message_handler_recv(struct ctdb_context *ctdb, ctdb_handle *handle)
480 struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
484 ret = ctdb_control_recv(ctdb, state, state, NULL, &res, NULL);
485 if (ret != 0 || res != 0) {
486 DEBUG(DEBUG_ERR,(__location__ " ctdb_remove_message_handler_recv failed\n"));
490 return state->status;
494 tell the daemon we no longer want a srvid
496 int ctdb_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid)
498 struct ctdb_client_control_state *state;
500 state = ctdb_remove_message_handler_send(ctdb, srvid, NULL, NULL);
502 DEBUG(DEBUG_ERR,(__location__ " ctdb_remove_message_handler_send() failed.\n"));
506 return ctdb_remove_message_handler_recv(ctdb, state);
516 * Create a database. If the database already exists this is a NOP.
519 ctdb_createdb_recv_cb(struct ctdb_client_control_state *state)
521 struct ctdb_control_cb_data *cb_data = state->async.private_data;
522 ctdb_createdb_cb callback = (ctdb_createdb_cb)cb_data->callback;
525 if (state->state != CTDB_CONTROL_DONE) {
526 DEBUG(DEBUG_ERR,(__location__ " control failed with state:%d and status:%d\n", state->state, state->status));
527 callback(-1, 0, cb_data->private_data);
531 if (state->outdata.dsize != sizeof(uint32_t)) {
532 DEBUG(DEBUG_ERR, (" Wrong size of data returned for CREATEDB control. Got %zd bytes but expected %zd\n", state->outdata.dsize, sizeof(uint32_t)));
533 callback(-1, 0, cb_data->private_data);
537 db_id = *(uint32_t *)state->outdata.dptr;
538 callback(state->status, db_id, cb_data->private_data);
543 ctdb_createdb_send(struct ctdb_context *ctdb, uint32_t destnode,
544 const char *name, int persistent,
546 ctdb_createdb_cb callback,
550 struct ctdb_client_control_state *state;
551 struct ctdb_control_cb_data *cb_data;
554 data.dptr = discard_const(name);
555 data.dsize = strlen(name)+1;
557 state = ctdb_control_send(ctdb, destnode, tdb_flags,
558 persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
562 DEBUG(DEBUG_ERR,(__location__ " Failed to send CREATEDB control\n"));
566 if (callback != NULL) {
567 cb_data = talloc(state, struct ctdb_control_cb_data);
568 cb_data->callback = callback;
569 cb_data->private_data = private_data;
571 state->async.fn = ctdb_createdb_recv_cb;
572 state->async.private_data = cb_data;
575 return (ctdb_handle *)state;
579 int ctdb_createdb_recv(struct ctdb_context *ctdb, ctdb_handle *handle, uint32_t *db_id)
581 struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
584 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
587 ret = ctdb_control_recv(ctdb, state, tmp_ctx, &data, &res, NULL);
588 if (ret != 0 || res != 0) {
589 DEBUG(DEBUG_ERR,(__location__ " ctdb_createdb_recv failed\n"));
590 talloc_free(tmp_ctx);
594 if (data.dsize != sizeof(uint32_t)) {
595 DEBUG(DEBUG_ERR, (__location__ " Wrong size of returned data. Got %zd bytes but expected %zd\n", data.dsize, sizeof(uint32_t)));
596 talloc_free(tmp_ctx);
601 *db_id = *(uint32_t *)data.dptr;
604 talloc_free(tmp_ctx);
605 return state->status;
608 int ctdb_createdb(struct ctdb_context *ctdb, uint32_t destnode, const char *name, int persistent, uint32_t tdb_flags, uint32_t *db_id)
610 struct ctdb_client_control_state *state;
612 state = ctdb_createdb_send(ctdb, destnode, name, persistent, tdb_flags, NULL, NULL);
614 DEBUG(DEBUG_ERR,(__location__ " ctdb_createdb_send() failed.\n"));
618 return ctdb_createdb_recv(ctdb, state, db_id);
626 * find the path to the tdb file of a database
629 ctdb_getdbpath_recv_cb(struct ctdb_client_control_state *state)
631 struct ctdb_control_cb_data *cb_data = state->async.private_data;
632 ctdb_getdbpath_cb callback = (ctdb_getdbpath_cb)cb_data->callback;
634 if (state->state != CTDB_CONTROL_DONE || state->status != 0) {
635 DEBUG(DEBUG_ERR,(__location__ " control failed with state:%d and status:%d\n", state->state, state->status));
636 callback(-1, NULL, cb_data->private_data);
640 callback(state->status, talloc_strdup(state->ctdb, (char *)state->outdata.dptr), cb_data->private_data);
644 ctdb_getdbpath_send(struct ctdb_context *ctdb, uint32_t destnode,
646 ctdb_getdbpath_cb callback,
649 struct ctdb_client_control_state *state;
650 struct ctdb_control_cb_data *cb_data;
653 data.dptr = (uint8_t *)&db_id;
654 data.dsize = sizeof(uint32_t);
656 state = ctdb_control_send(ctdb, destnode, 0,
657 CTDB_CONTROL_GETDBPATH, 0, data,
660 DEBUG(DEBUG_ERR,(__location__ " Failed to send GETDBPATH control\n"));
664 if (callback != NULL) {
665 cb_data = talloc(state, struct ctdb_control_cb_data);
666 cb_data->callback = callback;
667 cb_data->private_data = private_data;
669 state->async.fn = ctdb_getdbpath_recv_cb;
670 state->async.private_data = cb_data;
673 return (ctdb_handle *)state;
676 int ctdb_getdbpath_recv(struct ctdb_context *ctdb, ctdb_handle *handle, const char **path)
678 struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
681 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
688 ret = ctdb_control_recv(ctdb, state, tmp_ctx, &data, &res, NULL);
689 if (ret != 0 || res != 0) {
690 DEBUG(DEBUG_ERR,(__location__ " ctdb_getdbpath_recv failed\n"));
691 talloc_free(tmp_ctx);
695 if (state->status == 0 && path != NULL) {
696 *path = talloc_strdup(ctdb, (char *)data.dptr);
699 talloc_free(tmp_ctx);
700 return state->status;
703 int ctdb_getdbpath(struct ctdb_context *ctdb, uint32_t destnode,
707 struct ctdb_client_control_state *state;
709 state = ctdb_getdbpath_send(ctdb, destnode, db_id, NULL, NULL);
711 DEBUG(DEBUG_ERR,(__location__ " ctdb_getdbpath_send() failed.\n"));
715 return ctdb_getdbpath_recv(ctdb, state, path);
721 * Attach to a database
724 struct ctdb_attachdb_state {
725 enum control_state state;
726 struct ctdb_context *ctdb;
727 struct ctdb_db_context *ctdb_db;
728 struct ctdb_client_control_state *cdb_state;
729 struct ctdb_client_control_state *gdp_state;
733 ctdb_attachdb_cb callback;
739 ctdb_attachdb_recv2_cb(struct ctdb_client_control_state *state)
741 struct ctdb_attachdb_state *adb_state =
742 talloc_get_type(state->async.private_data,
743 struct ctdb_attachdb_state);
744 ctdb_attachdb_cb callback = (ctdb_attachdb_cb)adb_state->callback;
746 struct ctdb_db_context *ctdb_db =
747 talloc_get_type(adb_state->ctdb_db,
748 struct ctdb_db_context);
749 struct ctdb_context *ctdb =
750 talloc_get_type(ctdb_db->ctdb,
751 struct ctdb_context);
753 uint32_t tdb_flags = adb_state->tdb_flags;
754 bool persistent = adb_state->persistent;
756 if (state->state != CTDB_CONTROL_DONE || state->status != 0) {
757 DEBUG(DEBUG_ERR,(__location__ " getdbpath control failed with state:%d and status:%d\n", state->state, state->status));
758 adb_state->state = CTDB_CONTROL_ERROR;
759 if (callback != NULL) {
760 callback(-1, adb_state, NULL, adb_state->private_data);
764 ctdb_db->db_path = talloc_strdup(ctdb_db, (char *)state->outdata.dptr);
766 tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
767 if (ctdb->valgrinding) {
768 tdb_flags |= TDB_NOMMAP;
770 tdb_flags |= TDB_DISALLOW_NESTING;
772 ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
773 if (ctdb_db->ltdb == NULL) {
774 DEBUG(DEBUG_ERR, (__location__ " Failed to open tdb '%s'\n", ctdb_db->db_path));
775 adb_state->state = CTDB_CONTROL_ERROR;
776 if (callback != NULL) {
777 callback(-1, adb_state, NULL, adb_state->private_data);
782 ctdb_db->persistent = persistent;
784 DLIST_ADD(ctdb->db_list, ctdb_db);
786 /* add well known functions */
787 ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
788 ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
791 talloc_steal(ctdb, ctdb_db);
793 adb_state->state = CTDB_CONTROL_DONE;
794 if (callback != NULL) {
795 callback(0, adb_state, ctdb_db, adb_state->private_data);
800 ctdb_attachdb_recv1_cb(struct ctdb_client_control_state *state)
802 struct ctdb_attachdb_state *adb_state =
803 talloc_get_type(state->async.private_data,
804 struct ctdb_attachdb_state);
805 ctdb_attachdb_cb callback = (ctdb_attachdb_cb)adb_state->callback;
807 if (state->state != CTDB_CONTROL_DONE) {
808 DEBUG(DEBUG_ERR,(__location__ " createdb control failed with state:%d and status:%d\n", state->state, state->status));
809 adb_state->state = CTDB_CONTROL_ERROR;
810 if (callback != NULL) {
811 callback(-1, adb_state, NULL, adb_state->private_data);
816 if (state->outdata.dsize != sizeof(uint32_t)) {
817 DEBUG(DEBUG_ERR, (__location__ " Wrong size of data returned for CREATEDB control. Got %zd bytes but expected %zd\n", state->outdata.dsize, sizeof(uint32_t)));
818 adb_state->state = CTDB_CONTROL_ERROR;
819 if (callback != NULL) {
820 callback(-1, adb_state, NULL, adb_state->private_data);
825 adb_state->ctdb_db->db_id = *(uint32_t *)state->outdata.dptr;
827 adb_state->gdp_state = ctdb_getdbpath_send(adb_state->ctdb, CTDB_CURRENT_NODE, adb_state->ctdb_db->db_id, NULL, NULL);
829 DEBUG(DEBUG_ERR,(__location__ " ctdb_getdbpath_send() failed.\n"));
830 adb_state->state = CTDB_CONTROL_ERROR;
831 if (callback != NULL) {
832 callback(-1, adb_state, NULL, adb_state->private_data);
836 talloc_steal(adb_state, adb_state->gdp_state);
838 adb_state->gdp_state->async.fn = ctdb_attachdb_recv2_cb;
839 adb_state->gdp_state->async.private_data = adb_state;
843 ctdb_attachdb_send(struct ctdb_context *ctdb,
844 const char *name, int persistent, uint32_t tdb_flags,
845 ctdb_attachdb_cb callback,
848 struct ctdb_attachdb_state *state;
849 struct ctdb_db_context *ctdb_db;
851 ctdb_db = ctdb_db_handle(ctdb, name);
852 if (ctdb_db != NULL) {
853 DEBUG(DEBUG_ERR, (__location__ " There is already a database with this name. Can not attach twice.\n"));
857 state = talloc_zero(ctdb, struct ctdb_attachdb_state);
859 DEBUG(DEBUG_ERR,(__location__ " Failed to allocate attachdb_state\n"));
863 ctdb_db = talloc_zero(state, struct ctdb_db_context);
864 if (ctdb_db == NULL) {
865 DEBUG(DEBUG_ERR, (__location__ " Failed to allocate ctdb db context\n"));
870 state->state = CTDB_CONTROL_WAIT;
872 state->ctdb_db = ctdb_db;
873 state->tdb_flags = tdb_flags;
874 state->persistent = persistent?True:False;
876 ctdb_db->ctdb = ctdb;
877 ctdb_db->db_name = talloc_strdup(ctdb_db, name);
878 if (ctdb_db->db_name == NULL) {
879 DEBUG(DEBUG_ERR, (__location__ " Failed to strdup db name\n"));
884 state->cdb_state = ctdb_createdb_send(ctdb, CTDB_CURRENT_NODE,
885 name, persistent, tdb_flags,
887 if (state->cdb_state == NULL) {
888 DEBUG(DEBUG_ERR, (__location__ " Failed to send CREATEDB control\n"));
889 talloc_free(ctdb_db);
892 talloc_steal(state, state->cdb_state);
894 state->cdb_state->async.fn = ctdb_attachdb_recv1_cb;
895 state->cdb_state->async.private_data = state;
897 if (callback != NULL) {
898 state->callback = callback;
899 state->private_data = private_data;
902 return (ctdb_handle *)state;
905 int ctdb_attachdb_recv(struct ctdb_context *ctdb,
906 ctdb_handle *handle, struct ctdb_db_context **ctdb_db)
908 struct ctdb_attachdb_state *state = talloc_get_type(handle, struct ctdb_attachdb_state);
910 while (state->state == CTDB_CONTROL_WAIT) {
911 event_loop_once(ctdb->ev);
914 if (state->state != CTDB_CONTROL_DONE) {
915 if (ctdb_db != NULL) {
921 if (ctdb_db != NULL) {
922 *ctdb_db = state->ctdb_db;
929 int ctdb_attachdb(struct ctdb_context *ctdb,
930 const char *name, int persistent, uint32_t tdb_flags,
931 struct ctdb_db_context **ctdb_db)
936 handle = ctdb_attachdb_send(ctdb, name, persistent, tdb_flags, NULL, NULL);
937 if (handle == NULL) {
938 DEBUG(DEBUG_ERR, (__location__ " Failed to send attachdb control\n"));
942 ret = ctdb_attachdb_recv(ctdb, handle, ctdb_db);
944 DEBUG(DEBUG_ERR, (__location__ " receive of attachdb reply failed\n"));
955 * read a record from the database
957 * the returned data must be freed by using ctdb_free()
959 struct ctdb_call_cb_data {
960 struct ctdb_db_context *ctdb_db;
961 struct ctdb_record_handle *h;
968 /* These are not proper async methods yet */
970 ctdb_readrecordlock_send(struct ctdb_context *ctdb,
971 struct ctdb_db_context *ctdb_db,
973 ctdb_readrecordlock_cb callback,
976 struct ctdb_call_cb_data *state;
979 state = talloc_zero(ctdb, struct ctdb_call_cb_data);
981 DEBUG(DEBUG_ERR, (__location__ " Failed to send CALL\n"));
982 callback(-1, NULL, tdb_null, private_data);
986 state->h = ctdb_fetch_lock(ctdb_db, state, key, &data);
988 /* since this is fake async, invoke the callback immediately if set */
989 if (callback != NULL) {
990 callback(0, state, data, private_data);
997 int ctdb_readrecord_recv(struct ctdb_context *ctdb,
1001 int ctdb_readrecord(struct ctdb_context *ctdb,
1002 struct ctdb_db_context *ctdb_db_context,
1009 int ctdb_writerecord(ctdb_handle *handle,
1013 struct ctdb_call_cb_data *state = talloc_get_type(handle,
1014 struct ctdb_call_cb_data);
1016 struct ctdb_record_handle *h = talloc_get_type(state->h,
1017 struct ctdb_record_handle);
1019 if (h->ctdb_db->persistent) {
1020 DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
1024 return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);