tst.c: update to Ronnie's latest
[sahlberg/ctdb.git] / libctdb / tst.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <poll.h>
4 #include <fcntl.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <err.h>
8 #include <stdbool.h>
9 #include "lib/tdb/include/tdb.h"
10 #include "include/ctdb.h"
11
12 TDB_DATA key;
13
14 void msg_h(struct ctdb_connection *ctdb, uint64_t srvid, TDB_DATA data, void *private_data)
15 {
16         printf("Message received on port %d : %s\n", (int)srvid, data.dptr);
17 }
18
19 void pnn_cb(int32_t status, uint32_t pnn, void *private_data)
20 {
21         if (status != 0) {
22                 printf("Error reading PNN\n");
23                 return;
24         }
25         printf("status:%d pnn:%d\n", status, pnn);
26 }
27
28 void rm_cb(int status, uint32_t rm, void *private_data)
29 {
30         if (status != 0) {
31                 printf("Error reading RECMASTER\n");
32                 return;
33         }
34
35         printf("GETRECMASTER ASYNC: status:%d recmaster:%d\n", status, rm);
36 }
37
38
39 /*
40  * example on how to first read(non-existing recortds are implicitely created
41  * on demand) a record and change it in the callback.
42  * This forms the atom for the read-modify-write cycle.
43  *
44  * Pure read, or pure write are just special cases of this cycle.
45  */
46 void rrl_cb(int32_t status, struct ctdb_lock *lock, TDB_DATA outdata, void *private_data)
47 {
48         TDB_DATA data;
49         char tmp[256];
50
51         if (status != 0) {
52                 printf("rrl_cb returned error: status %d\n", status);
53                 return;
54         }
55
56         printf("rrl size:%d data:%.*s\n", outdata.dsize,
57                outdata.dsize, outdata.dptr);
58         if (outdata.dsize == 0) {
59                 tmp[0] = 0;
60         } else {
61                 strcpy(tmp, outdata.dptr);
62         }
63         strcat(tmp, "*");
64
65         data.dptr  = tmp;
66         data.dsize = strlen(tmp) + 1;
67         ctdb_writerecord(lock, data);
68
69         printf("Wrote new record : %s\n", tmp);
70
71         ctdb_release_lock(lock);
72 }
73
74 static bool registered = false;
75 void message_handler_cb(int status, void *private_data)
76 {
77         printf("Message handler registered: %i\n", status);
78         registered = true;
79 }
80
81 int main(int argc, char *argv[])
82 {
83         struct ctdb_connection *ctdb_connection;
84         struct ctdb_request *handle;
85         struct ctdb_db *ctdb_db_context;
86         struct pollfd pfd;
87         uint32_t recmaster;
88         int ret;
89         TDB_DATA msg;
90
91         ctdb_connection = ctdb_connect("/tmp/ctdb.socket");
92         if (!ctdb_connection)
93                 err(1, "Connecting to /tmp/ctdb.socket");
94
95         pfd.fd = ctdb_get_fd(ctdb_connection);
96
97         handle = ctdb_set_message_handler_send(ctdb_connection, 55, message_handler_cb, msg_h, NULL);
98         if (handle == NULL) {
99                 printf("Failed to register message port\n");
100                 exit(10);
101         }
102
103         /* Hack for testing: this makes sure registration goes out. */
104         while (!registered) {
105                 ctdb_service(ctdb_connection, POLLIN|POLLOUT);
106         }
107
108         msg.dptr="HelloWorld";
109         msg.dsize = strlen(msg.dptr);
110
111         ret = ctdb_send_message(ctdb_connection, 0, 55, msg);
112         if (ret != 0) {
113                 printf("Failed to send message. Aborting\n");
114                 exit(10);
115         }
116
117         handle = ctdb_getrecmaster_send(ctdb_connection, 0, rm_cb, NULL);
118         if (handle == NULL) {
119                 printf("Failed to send get_recmaster control\n");
120                 exit(10);
121         }
122
123         ctdb_db_context = ctdb_attachdb(ctdb_connection, "test_test.tdb", 0, 0);
124         if (!ctdb_db_context) {
125                 printf("Failed to attach to database\n");
126                 exit(10);
127         }
128
129         /*
130          * SYNC call with callback to read the recmaster
131          * calls the blocking sync function.
132          * Avoid this mode for performance critical tasks
133          */
134         ret = ctdb_getrecmaster(ctdb_connection, CTDB_CURRENT_NODE, &recmaster);
135         if (ret != 0) {
136                 printf("Failed to receive response to getrecmaster\n");
137                 exit(10);
138         }
139         printf("GETRECMASTER SYNC: status:%d recmaster:%d\n", ret, recmaster);
140
141
142         handle = ctdb_getpnn_send(ctdb_connection, CTDB_CURRENT_NODE,
143                                   pnn_cb, NULL);
144         if (handle == NULL) {
145                 printf("Failed to send get_pnn control\n");
146                 exit(10);
147         }
148
149         handle = ctdb_readrecordlock_send(ctdb_db_context, key, rrl_cb,
150                                           ctdb_db_context);
151         if (handle == NULL) {
152                 printf("Failed to send READRECORDLOCK\n");
153                 exit(10);
154         }
155
156         for (;;) {
157
158           pfd.events = ctdb_which_events(ctdb_connection);
159           if (poll(&pfd, 1, -1) < 0) {
160             printf("Poll failed");
161             exit(10);
162           }
163           if (ctdb_service(ctdb_connection, pfd.revents) < 0) {
164                   err(1, "Failed to service");
165           }
166         }
167
168         return 0;
169 }