2 * Example program to demonstrate the libctdb api
4 * This program needs to be linked with libtdb.
5 * (libtdb and libtdb-devel packages)
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/>.
28 #include "lib/tdb/include/tdb.h"
29 #include "include/ctdb.h"
33 void msg_h(struct ctdb_connection *ctdb, uint64_t srvid, TDB_DATA data, void *private_data)
35 printf("Message received on port %d : %s\n", (int)srvid, data.dptr);
38 static void pnn_cb(struct ctdb_connection *ctdb,
39 struct ctdb_request *req, void *private)
44 status = ctdb_getpnn_recv(req, &pnn);
46 printf("Error reading PNN\n");
49 printf("status:%d pnn:%d\n", status, pnn);
52 static void rm_cb(struct ctdb_connection *ctdb,
53 struct ctdb_request *req, void *private)
58 status = ctdb_getrecmaster_recv(req, &rm);
60 printf("Error reading RECMASTER\n");
64 printf("GETRECMASTER ASYNC: status:%d recmaster:%d\n", status, rm);
68 * example on how to first read(non-existing recortds are implicitely created
69 * on demand) a record and change it in the callback.
70 * This forms the atom for the read-modify-write cycle.
72 * Pure read, or pure write are just special cases of this cycle.
74 static void rrl_cb(struct ctdb_connection *ctdb,
75 struct ctdb_request *req, void *private)
77 struct ctdb_lock *lock;
82 lock = ctdb_readrecordlock_recv(private, req, &outdata);
84 printf("rrl_cb returned error\n");
88 printf("rrl size:%d data:%.*s\n", outdata.dsize,
89 outdata.dsize, outdata.dptr);
90 if (outdata.dsize == 0) {
93 strcpy(tmp, outdata.dptr);
98 data.dsize = strlen(tmp) + 1;
99 ctdb_writerecord(lock, data);
101 printf("Wrote new record : %s\n", tmp);
103 ctdb_release_lock(lock);
106 static bool registered = false;
107 void message_handler_cb(struct ctdb_connection *ctdb,
108 struct ctdb_request *req, void *private)
110 if (ctdb_set_message_handler_recv(ctdb, req) != 0) {
111 err(1, "registering message");
113 printf("Message handler registered\n");
117 int main(int argc, char *argv[])
119 struct ctdb_connection *ctdb_connection;
120 struct ctdb_request *handle;
121 struct ctdb_db *ctdb_db_context;
127 ctdb_connection = ctdb_connect("/tmp/ctdb.socket");
128 if (!ctdb_connection)
129 err(1, "Connecting to /tmp/ctdb.socket");
131 pfd.fd = ctdb_get_fd(ctdb_connection);
133 handle = ctdb_set_message_handler_send(ctdb_connection, 55, msg_h,
134 message_handler_cb, NULL);
135 if (handle == NULL) {
136 printf("Failed to register message port\n");
140 /* Hack for testing: this makes sure registration goes out. */
141 while (!registered) {
142 ctdb_service(ctdb_connection, POLLIN|POLLOUT);
145 msg.dptr="HelloWorld";
146 msg.dsize = strlen(msg.dptr);
148 ret = ctdb_send_message(ctdb_connection, 0, 55, msg);
150 printf("Failed to send message. Aborting\n");
154 handle = ctdb_getrecmaster_send(ctdb_connection, 0, rm_cb, NULL);
155 if (handle == NULL) {
156 printf("Failed to send get_recmaster control\n");
160 ctdb_db_context = ctdb_attachdb(ctdb_connection, "test_test.tdb", 0, 0);
161 if (!ctdb_db_context) {
162 printf("Failed to attach to database\n");
167 * SYNC call with callback to read the recmaster
168 * calls the blocking sync function.
169 * Avoid this mode for performance critical tasks
171 ret = ctdb_getrecmaster(ctdb_connection, CTDB_CURRENT_NODE, &recmaster);
173 printf("Failed to receive response to getrecmaster\n");
176 printf("GETRECMASTER SYNC: status:%d recmaster:%d\n", ret, recmaster);
179 handle = ctdb_getpnn_send(ctdb_connection, CTDB_CURRENT_NODE,
181 if (handle == NULL) {
182 printf("Failed to send get_pnn control\n");
186 if (!ctdb_readrecordlock_send(ctdb_db_context, key, &handle,
187 rrl_cb, ctdb_db_context)) {
188 printf("Failed to send READRECORDLOCK\n");
192 printf("READRECORDLOCK is async\n");
196 pfd.events = ctdb_which_events(ctdb_connection);
197 if (poll(&pfd, 1, -1) < 0) {
198 printf("Poll failed");
201 if (ctdb_service(ctdb_connection, pfd.revents) < 0) {
202 err(1, "Failed to service");