LibCTDB: add get persistent db seqnum control
[kai/samba-autobuild/.git] / ctdb / libctdb / control.c
1 /*
2    Misc control routines of libctdb
3
4    Copyright (C) Rusty Russell 2010
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include <string.h>
20 #include <ctdb.h>
21 #include <ctdb_protocol.h>
22 #include "libctdb_private.h"
23
24 /* Remove type-safety macros. */
25 #undef ctdb_getrecmaster_send
26 #undef ctdb_getrecmode_send
27 #undef ctdb_getpnn_send
28 #undef ctdb_getnodemap_send
29 #undef ctdb_getpublicips_send
30 #undef ctdb_getdbseqnum_send
31
32 bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb,
33                            struct ctdb_request *req, uint32_t *recmaster)
34 {
35         struct ctdb_reply_control *reply;
36
37         reply = unpack_reply_control(req, CTDB_CONTROL_GET_RECMASTER);
38         if (!reply) {
39                 return false;
40         }
41         if (reply->status == -1) {
42                 DEBUG(ctdb, LOG_ERR, "ctdb_getrecmaster_recv: status -1");
43                 return false;
44         }
45         *recmaster = reply->status;
46         return true;
47 }
48
49 struct ctdb_request *ctdb_getrecmaster_send(struct ctdb_connection *ctdb,
50                                             uint32_t destnode,
51                                             ctdb_callback_t callback,
52                                             void *private_data)
53 {
54         return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_RECMASTER,
55                                         destnode, NULL, 0,
56                                         callback, private_data);
57 }
58
59 bool ctdb_getrecmode_recv(struct ctdb_connection *ctdb,
60                           struct ctdb_request *req, uint32_t *recmode)
61 {
62         struct ctdb_reply_control *reply;
63
64         reply = unpack_reply_control(req, CTDB_CONTROL_GET_RECMODE);
65         if (!reply) {
66                 return false;
67         }
68         if (reply->status == -1) {
69                 DEBUG(ctdb, LOG_ERR, "ctdb_getrecmode_recv: status -1");
70                 return false;
71         }
72         *recmode = reply->status;
73         return true;
74 }
75
76 struct ctdb_request *ctdb_getrecmode_send(struct ctdb_connection *ctdb,
77                                             uint32_t destnode,
78                                             ctdb_callback_t callback,
79                                             void *private_data)
80 {
81         return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_RECMODE,
82                                         destnode, NULL, 0,
83                                         callback, private_data);
84 }
85
86 bool ctdb_getpnn_recv(struct ctdb_connection *ctdb,
87                      struct ctdb_request *req, uint32_t *pnn)
88 {
89         struct ctdb_reply_control *reply;
90
91         reply = unpack_reply_control(req, CTDB_CONTROL_GET_PNN);
92         if (!reply) {
93                 return false;
94         }
95         if (reply->status == -1) {
96                 DEBUG(ctdb, LOG_ERR, "ctdb_getpnn_recv: status -1");
97                 return false;
98         }
99         *pnn = reply->status;
100         return true;
101 }
102
103 struct ctdb_request *ctdb_getpnn_send(struct ctdb_connection *ctdb,
104                                       uint32_t destnode,
105                                       ctdb_callback_t callback,
106                                       void *private_data)
107 {
108         return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PNN, destnode,
109                                         NULL, 0, callback, private_data);
110 }
111
112 bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb,
113                       struct ctdb_request *req, struct ctdb_node_map **nodemap)
114 {
115         struct ctdb_reply_control *reply;
116
117         *nodemap = NULL;
118         reply = unpack_reply_control(req, CTDB_CONTROL_GET_NODEMAP);
119         if (!reply) {
120                 return false;
121         }
122         if (reply->status == -1) {
123                 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: status -1");
124                 return false;
125         }
126         if (reply->datalen == 0) {
127                 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: returned data is 0 bytes");
128                 return false;
129         }
130
131         *nodemap = malloc(reply->datalen);
132         if (*nodemap == NULL) {
133                 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: failed to malloc buffer");
134                 return false;
135         }
136         memcpy(*nodemap, reply->data, reply->datalen);
137
138         return true;
139 }
140 struct ctdb_request *ctdb_getnodemap_send(struct ctdb_connection *ctdb,
141                                           uint32_t destnode,
142                                           ctdb_callback_t callback,
143                                           void *private_data)
144 {
145         return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_NODEMAP,
146                                         destnode,
147                                         NULL, 0, callback, private_data);
148 }
149
150 void ctdb_free_nodemap(struct ctdb_node_map *nodemap)
151 {
152         if (nodemap == NULL) {
153                 return;
154         }
155         free(nodemap);
156 }
157
158 bool ctdb_getpublicips_recv(struct ctdb_connection *ctdb,
159                             struct ctdb_request *req,
160                             struct ctdb_all_public_ips **ips)
161 {
162         struct ctdb_reply_control *reply;
163
164         *ips = NULL;
165         reply = unpack_reply_control(req, CTDB_CONTROL_GET_PUBLIC_IPS);
166         if (!reply) {
167                 return false;
168         }
169         if (reply->status == -1) {
170                 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: status -1");
171                 return false;
172         }
173         if (reply->datalen == 0) {
174                 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: returned data is 0 bytes");
175                 return false;
176         }
177
178         *ips = malloc(reply->datalen);
179         if (*ips == NULL) {
180                 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: failed to malloc buffer");
181                 return false;
182         }
183         memcpy(*ips, reply->data, reply->datalen);
184
185         return true;
186 }
187 struct ctdb_request *ctdb_getpublicips_send(struct ctdb_connection *ctdb,
188                                             uint32_t destnode,
189                                             ctdb_callback_t callback,
190                                             void *private_data)
191 {
192         return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PUBLIC_IPS,
193                                         destnode,
194                                         NULL, 0, callback, private_data);
195 }
196
197 void ctdb_free_publicips(struct ctdb_all_public_ips *ips)
198 {
199         if (ips == NULL) {
200                 return;
201         }
202         free(ips);
203 }
204
205 bool ctdb_getdbseqnum_recv(struct ctdb_connection *ctdb,
206                            struct ctdb_request *req, uint64_t *seqnum)
207 {
208         struct ctdb_reply_control *reply;
209
210         reply = unpack_reply_control(req, CTDB_CONTROL_GET_DB_SEQNUM);
211         if (!reply) {
212                 return false;
213         }
214         if (reply->status == -1) {
215                 DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum_recv: status -1");
216                 return false;
217         }
218
219         if (reply->datalen != sizeof(uint64_t)) {
220                 DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum wrong size of data was %d but expected %d bytes", reply->datalen, (int)sizeof(uint64_t));
221                 return false;
222         }
223
224         *seqnum = *((uint64_t *)reply->data);
225
226         return true;
227 }
228
229 struct ctdb_request *ctdb_getdbseqnum_send(struct ctdb_connection *ctdb,
230                                             uint32_t destnode,
231                                             uint32_t dbid,
232                                             ctdb_callback_t callback,
233                                             void *private_data)
234 {
235         uint64_t indata;
236
237         *((uint32_t *)&indata) = dbid;
238
239         return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_DB_SEQNUM,
240                                         destnode, &indata, sizeof(uint64_t),
241                                         callback, private_data);
242 }