2 Misc control routines of libctdb
4 Copyright (C) Rusty Russell 2010
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.
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.
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/>.
21 #include <ctdb_protocol.h>
22 #include "libctdb_private.h"
24 /* Remove type-safety macros. */
25 #undef ctdb_getrecmaster_send
26 #undef ctdb_getrecmode_send
27 #undef ctdb_getpnn_send
28 #undef ctdb_check_message_handlers_send
29 #undef ctdb_getnodemap_send
30 #undef ctdb_getpublicips_send
31 #undef ctdb_getdbseqnum_send
32 #undef ctdb_getifaces_send
33 #undef ctdb_getvnnmap_send
35 bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb,
36 struct ctdb_request *req, uint32_t *recmaster)
38 struct ctdb_reply_control *reply;
40 reply = unpack_reply_control(req, CTDB_CONTROL_GET_RECMASTER);
44 if (reply->status == -1) {
45 DEBUG(ctdb, LOG_ERR, "ctdb_getrecmaster_recv: status -1");
48 *recmaster = reply->status;
52 struct ctdb_request *ctdb_getrecmaster_send(struct ctdb_connection *ctdb,
54 ctdb_callback_t callback,
57 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_RECMASTER,
59 callback, private_data);
62 bool ctdb_getrecmode_recv(struct ctdb_connection *ctdb,
63 struct ctdb_request *req, uint32_t *recmode)
65 struct ctdb_reply_control *reply;
67 reply = unpack_reply_control(req, CTDB_CONTROL_GET_RECMODE);
71 if (reply->status == -1) {
72 DEBUG(ctdb, LOG_ERR, "ctdb_getrecmode_recv: status -1");
75 *recmode = reply->status;
79 struct ctdb_request *ctdb_getrecmode_send(struct ctdb_connection *ctdb,
81 ctdb_callback_t callback,
84 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_RECMODE,
86 callback, private_data);
89 bool ctdb_getpnn_recv(struct ctdb_connection *ctdb,
90 struct ctdb_request *req, uint32_t *pnn)
92 struct ctdb_reply_control *reply;
94 reply = unpack_reply_control(req, CTDB_CONTROL_GET_PNN);
98 if (reply->status == -1) {
99 DEBUG(ctdb, LOG_ERR, "ctdb_getpnn_recv: status -1");
102 *pnn = reply->status;
106 struct ctdb_request *ctdb_getpnn_send(struct ctdb_connection *ctdb,
108 ctdb_callback_t callback,
111 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PNN, destnode,
112 NULL, 0, callback, private_data);
115 bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb,
116 struct ctdb_request *req, struct ctdb_node_map **nodemap)
118 struct ctdb_reply_control *reply;
121 reply = unpack_reply_control(req, CTDB_CONTROL_GET_NODEMAP);
125 if (reply->status == -1) {
126 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: status -1");
129 if (reply->datalen == 0) {
130 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: returned data is 0 bytes");
134 *nodemap = malloc(reply->datalen);
135 if (*nodemap == NULL) {
136 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: failed to malloc buffer");
139 memcpy(*nodemap, reply->data, reply->datalen);
143 struct ctdb_request *ctdb_getnodemap_send(struct ctdb_connection *ctdb,
145 ctdb_callback_t callback,
148 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_NODEMAP,
150 NULL, 0, callback, private_data);
153 void ctdb_free_nodemap(struct ctdb_node_map *nodemap)
155 if (nodemap == NULL) {
161 bool ctdb_getpublicips_recv(struct ctdb_connection *ctdb,
162 struct ctdb_request *req,
163 struct ctdb_all_public_ips **ips)
165 struct ctdb_reply_control *reply;
168 reply = unpack_reply_control(req, CTDB_CONTROL_GET_PUBLIC_IPS);
172 if (reply->status == -1) {
173 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: status -1");
176 if (reply->datalen == 0) {
177 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: returned data is 0 bytes");
181 *ips = malloc(reply->datalen);
183 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: failed to malloc buffer");
186 memcpy(*ips, reply->data, reply->datalen);
190 struct ctdb_request *ctdb_getpublicips_send(struct ctdb_connection *ctdb,
192 ctdb_callback_t callback,
195 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PUBLIC_IPS,
197 NULL, 0, callback, private_data);
200 void ctdb_free_publicips(struct ctdb_all_public_ips *ips)
208 bool ctdb_getdbseqnum_recv(struct ctdb_connection *ctdb,
209 struct ctdb_request *req, uint64_t *seqnum)
211 struct ctdb_reply_control *reply;
213 reply = unpack_reply_control(req, CTDB_CONTROL_GET_DB_SEQNUM);
217 if (reply->status == -1) {
218 DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum_recv: status -1");
222 if (reply->datalen != sizeof(uint64_t)) {
223 DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum wrong size of data was %d but expected %d bytes", reply->datalen, (int)sizeof(uint64_t));
227 *seqnum = *((uint64_t *)reply->data);
232 struct ctdb_request *ctdb_getdbseqnum_send(struct ctdb_connection *ctdb,
235 ctdb_callback_t callback,
240 *((uint32_t *)&indata) = dbid;
242 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_DB_SEQNUM,
243 destnode, &indata, sizeof(uint64_t),
244 callback, private_data);
247 bool ctdb_check_message_handlers_recv(struct ctdb_connection *ctdb,
248 struct ctdb_request *req,
249 uint32_t num, uint8_t *result)
251 struct ctdb_reply_control *reply;
254 reply = unpack_reply_control(req, CTDB_CONTROL_CHECK_SRVIDS);
258 if (reply->status == -1) {
259 DEBUG(ctdb, LOG_ERR, "ctdb_check_message_handlers_recv: status -1");
263 count = (num + 7) / 8;
264 if (count != reply->datalen) {
265 DEBUG(ctdb, LOG_ERR, "ctdb_check_message_handlers_recv: wrong amount of data returned, expected %d bytes for %d srvids but received %d bytes", count, num, reply->datalen);
269 for (i = 0; i < num; i++) {
270 result[i] = !!(reply->data[i / 8] & (1 << (i % 8)));
276 struct ctdb_request *
277 ctdb_check_message_handlers_send(struct ctdb_connection *ctdb,
281 ctdb_callback_t callback,
284 return new_ctdb_control_request(ctdb, CTDB_CONTROL_CHECK_SRVIDS,
286 mhs, num * sizeof(uint64_t) ,
287 callback, private_data);
291 bool ctdb_getifaces_recv(struct ctdb_connection *ctdb,
292 struct ctdb_request *req,
293 struct ctdb_ifaces_list **ifaces)
295 struct ctdb_reply_control *reply;
296 struct ctdb_ifaces_list *ifc;
300 reply = unpack_reply_control(req, CTDB_CONTROL_GET_IFACES);
304 if (reply->status == -1) {
305 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: status -1");
308 if (reply->datalen == 0) {
309 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: returned data is 0 bytes");
313 len = offsetof(struct ctdb_ifaces_list, ifaces);
314 if (len > reply->datalen) {
315 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: returned data is %d bytes but %d is minimum", reply->datalen, (int)offsetof(struct ctdb_ifaces_list, ifaces));
319 ifc = (struct ctdb_ifaces_list *)(reply->data);
320 len += ifc->num * sizeof(struct ctdb_iface_info);
322 if (len != reply->datalen) {
323 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: returned data is %d bytes but should be %d", reply->datalen, len);
327 ifc = malloc(reply->datalen);
329 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: failed to malloc buffer");
332 memcpy(ifc, reply->data, reply->datalen);
334 /* make sure we null terminate the returned strings */
335 for (i = 0; i < ifc->num; i++) {
336 ifc->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
344 void ctdb_free_ifaces(struct ctdb_ifaces_list *ifaces)
349 struct ctdb_request *ctdb_getifaces_send(struct ctdb_connection *ctdb,
351 ctdb_callback_t callback,
354 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_IFACES,
356 NULL, 0, callback, private_data);
359 bool ctdb_getvnnmap_recv(struct ctdb_connection *ctdb,
360 struct ctdb_request *req,
361 struct ctdb_vnn_map **vnnmap)
363 struct ctdb_reply_control *reply;
364 struct ctdb_vnn_map_wire *map;
365 struct ctdb_vnn_map *tmap;
369 reply = unpack_reply_control(req, CTDB_CONTROL_GETVNNMAP);
373 if (reply->status == -1) {
374 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: status -1");
377 if (reply->datalen == 0) {
378 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: returned data is 0 bytes");
382 len = offsetof(struct ctdb_vnn_map_wire, map);
383 if (len > reply->datalen) {
384 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: returned data is %d bytes but %d is minimum", reply->datalen, (int)offsetof(struct ctdb_vnn_map_wire, map));
388 map = (struct ctdb_vnn_map_wire *)(reply->data);
389 len += map->size * sizeof(uint32_t);
391 if (len != reply->datalen) {
392 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: returned data is %d bytes but should be %d", reply->datalen, len);
396 tmap = malloc(sizeof(struct ctdb_vnn_map));
398 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: failed to malloc buffer");
402 tmap->generation = map->generation;
403 tmap->size = map->size;
404 tmap->map = malloc(sizeof(uint32_t) * map->size);
405 if (tmap->map == NULL) {
406 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: failed to malloc buffer");
411 memcpy(tmap->map, map->map, sizeof(uint32_t)*map->size);
418 void ctdb_free_vnnmap(struct ctdb_vnn_map *vnnmap)
424 struct ctdb_request *ctdb_getvnnmap_send(struct ctdb_connection *ctdb,
426 ctdb_callback_t callback,
429 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GETVNNMAP,
431 NULL, 0, callback, private_data);