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/>.
19 #include <sys/socket.h>
22 #include <ctdb_protocol.h>
23 #include "libctdb_private.h"
25 /* Remove type-safety macros. */
26 #undef ctdb_getrecmaster_send
27 #undef ctdb_getrecmode_send
28 #undef ctdb_getpnn_send
29 #undef ctdb_getdbstat_send
30 #undef ctdb_check_message_handlers_send
31 #undef ctdb_getnodemap_send
32 #undef ctdb_getpublicips_send
33 #undef ctdb_getdbseqnum_send
34 #undef ctdb_getifaces_send
35 #undef ctdb_getvnnmap_send
37 bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb,
38 struct ctdb_request *req, uint32_t *recmaster)
40 struct ctdb_reply_control *reply;
42 reply = unpack_reply_control(req, CTDB_CONTROL_GET_RECMASTER);
46 if (reply->status == -1) {
47 DEBUG(ctdb, LOG_ERR, "ctdb_getrecmaster_recv: status -1");
50 *recmaster = reply->status;
54 struct ctdb_request *ctdb_getrecmaster_send(struct ctdb_connection *ctdb,
56 ctdb_callback_t callback,
59 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_RECMASTER,
61 callback, private_data);
64 bool ctdb_getrecmode_recv(struct ctdb_connection *ctdb,
65 struct ctdb_request *req, uint32_t *recmode)
67 struct ctdb_reply_control *reply;
69 reply = unpack_reply_control(req, CTDB_CONTROL_GET_RECMODE);
73 if (reply->status == -1) {
74 DEBUG(ctdb, LOG_ERR, "ctdb_getrecmode_recv: status -1");
77 *recmode = reply->status;
81 struct ctdb_request *ctdb_getrecmode_send(struct ctdb_connection *ctdb,
83 ctdb_callback_t callback,
86 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_RECMODE,
88 callback, private_data);
91 bool ctdb_getpnn_recv(struct ctdb_connection *ctdb,
92 struct ctdb_request *req, uint32_t *pnn)
94 struct ctdb_reply_control *reply;
96 reply = unpack_reply_control(req, CTDB_CONTROL_GET_PNN);
100 if (reply->status == -1) {
101 DEBUG(ctdb, LOG_ERR, "ctdb_getpnn_recv: status -1");
104 *pnn = reply->status;
108 struct ctdb_request *ctdb_getpnn_send(struct ctdb_connection *ctdb,
110 ctdb_callback_t callback,
113 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PNN, destnode,
114 NULL, 0, callback, private_data);
117 bool ctdb_getdbstat_recv(struct ctdb_connection *ctdb,
118 struct ctdb_request *req,
119 struct ctdb_db_statistics **stat)
121 struct ctdb_reply_control *reply;
122 struct ctdb_db_statistics *s;
124 reply = unpack_reply_control(req, CTDB_CONTROL_GET_DB_STATISTICS);
128 if (reply->status == -1) {
129 DEBUG(ctdb, LOG_ERR, "ctdb_getpnn_recv: status -1");
132 if (reply->datalen != sizeof(struct ctdb_db_statistics)) {
133 DEBUG(ctdb, LOG_ERR, "ctdb_getdbstat_recv: returned data is %d bytes but should be %d", reply->datalen, (int)sizeof(struct ctdb_db_statistics));
137 s = malloc(sizeof(struct ctdb_db_statistics));
141 memcpy(s, reply->data, sizeof(struct ctdb_db_statistics));
147 struct ctdb_request *ctdb_getdbstat_send(struct ctdb_connection *ctdb,
150 ctdb_callback_t callback,
153 uint32_t indata = db_id;
155 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_DB_STATISTICS, destnode,
156 &indata, sizeof(indata), callback, private_data);
159 void ctdb_free_dbstat(struct ctdb_db_statistics *stat)
167 bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb,
168 struct ctdb_request *req, struct ctdb_node_map **nodemap)
170 struct ctdb_reply_control *reply;
173 reply = unpack_reply_control(req, CTDB_CONTROL_GET_NODEMAP);
177 if (reply->status == -1) {
178 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: status -1");
181 if (reply->datalen == 0) {
182 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: returned data is 0 bytes");
186 *nodemap = malloc(reply->datalen);
187 if (*nodemap == NULL) {
188 DEBUG(ctdb, LOG_ERR, "ctdb_getnodemap_recv: failed to malloc buffer");
191 memcpy(*nodemap, reply->data, reply->datalen);
195 struct ctdb_request *ctdb_getnodemap_send(struct ctdb_connection *ctdb,
197 ctdb_callback_t callback,
200 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_NODEMAP,
202 NULL, 0, callback, private_data);
205 void ctdb_free_nodemap(struct ctdb_node_map *nodemap)
207 if (nodemap == NULL) {
213 bool ctdb_getpublicips_recv(struct ctdb_connection *ctdb,
214 struct ctdb_request *req,
215 struct ctdb_all_public_ips **ips)
217 struct ctdb_reply_control *reply;
220 reply = unpack_reply_control(req, CTDB_CONTROL_GET_PUBLIC_IPS);
224 if (reply->status == -1) {
225 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: status -1");
228 if (reply->datalen == 0) {
229 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: returned data is 0 bytes");
233 *ips = malloc(reply->datalen);
235 DEBUG(ctdb, LOG_ERR, "ctdb_getpublicips_recv: failed to malloc buffer");
238 memcpy(*ips, reply->data, reply->datalen);
242 struct ctdb_request *ctdb_getpublicips_send(struct ctdb_connection *ctdb,
244 ctdb_callback_t callback,
247 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_PUBLIC_IPS,
249 NULL, 0, callback, private_data);
252 void ctdb_free_publicips(struct ctdb_all_public_ips *ips)
260 bool ctdb_getdbseqnum_recv(struct ctdb_connection *ctdb,
261 struct ctdb_request *req, uint64_t *seqnum)
263 struct ctdb_reply_control *reply;
265 reply = unpack_reply_control(req, CTDB_CONTROL_GET_DB_SEQNUM);
269 if (reply->status == -1) {
270 DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum_recv: status -1");
274 if (reply->datalen != sizeof(uint64_t)) {
275 DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum wrong size of data was %d but expected %d bytes", reply->datalen, (int)sizeof(uint64_t));
279 *seqnum = *((uint64_t *)reply->data);
284 struct ctdb_request *ctdb_getdbseqnum_send(struct ctdb_connection *ctdb,
287 ctdb_callback_t callback,
292 *((uint32_t *)&indata) = dbid;
294 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_DB_SEQNUM,
295 destnode, &indata, sizeof(uint64_t),
296 callback, private_data);
299 bool ctdb_check_message_handlers_recv(struct ctdb_connection *ctdb,
300 struct ctdb_request *req,
301 uint32_t num, uint8_t *result)
303 struct ctdb_reply_control *reply;
306 reply = unpack_reply_control(req, CTDB_CONTROL_CHECK_SRVIDS);
310 if (reply->status == -1) {
311 DEBUG(ctdb, LOG_ERR, "ctdb_check_message_handlers_recv: status -1");
315 count = (num + 7) / 8;
316 if (count != reply->datalen) {
317 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);
321 for (i = 0; i < num; i++) {
322 result[i] = !!(reply->data[i / 8] & (1 << (i % 8)));
328 struct ctdb_request *
329 ctdb_check_message_handlers_send(struct ctdb_connection *ctdb,
333 ctdb_callback_t callback,
336 return new_ctdb_control_request(ctdb, CTDB_CONTROL_CHECK_SRVIDS,
338 mhs, num * sizeof(uint64_t) ,
339 callback, private_data);
343 bool ctdb_getifaces_recv(struct ctdb_connection *ctdb,
344 struct ctdb_request *req,
345 struct ctdb_ifaces_list **ifaces)
347 struct ctdb_reply_control *reply;
348 struct ctdb_ifaces_list *ifc;
352 reply = unpack_reply_control(req, CTDB_CONTROL_GET_IFACES);
356 if (reply->status == -1) {
357 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: status -1");
360 if (reply->datalen == 0) {
361 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: returned data is 0 bytes");
365 len = offsetof(struct ctdb_ifaces_list, ifaces);
366 if (len > reply->datalen) {
367 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));
371 ifc = (struct ctdb_ifaces_list *)(reply->data);
372 len += ifc->num * sizeof(struct ctdb_iface_info);
374 if (len != reply->datalen) {
375 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: returned data is %d bytes but should be %d", reply->datalen, len);
379 ifc = malloc(reply->datalen);
381 DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: failed to malloc buffer");
384 memcpy(ifc, reply->data, reply->datalen);
386 /* make sure we null terminate the returned strings */
387 for (i = 0; i < ifc->num; i++) {
388 ifc->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
396 void ctdb_free_ifaces(struct ctdb_ifaces_list *ifaces)
401 struct ctdb_request *ctdb_getifaces_send(struct ctdb_connection *ctdb,
403 ctdb_callback_t callback,
406 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_IFACES,
408 NULL, 0, callback, private_data);
411 bool ctdb_getvnnmap_recv(struct ctdb_connection *ctdb,
412 struct ctdb_request *req,
413 struct ctdb_vnn_map **vnnmap)
415 struct ctdb_reply_control *reply;
416 struct ctdb_vnn_map_wire *map;
417 struct ctdb_vnn_map *tmap;
421 reply = unpack_reply_control(req, CTDB_CONTROL_GETVNNMAP);
425 if (reply->status == -1) {
426 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: status -1");
429 if (reply->datalen == 0) {
430 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: returned data is 0 bytes");
434 len = offsetof(struct ctdb_vnn_map_wire, map);
435 if (len > reply->datalen) {
436 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));
440 map = (struct ctdb_vnn_map_wire *)(reply->data);
441 len += map->size * sizeof(uint32_t);
443 if (len != reply->datalen) {
444 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: returned data is %d bytes but should be %d", reply->datalen, len);
448 tmap = malloc(sizeof(struct ctdb_vnn_map));
450 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: failed to malloc buffer");
454 tmap->generation = map->generation;
455 tmap->size = map->size;
456 tmap->map = malloc(sizeof(uint32_t) * map->size);
457 if (tmap->map == NULL) {
458 DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: failed to malloc buffer");
463 memcpy(tmap->map, map->map, sizeof(uint32_t)*map->size);
470 void ctdb_free_vnnmap(struct ctdb_vnn_map *vnnmap)
476 struct ctdb_request *ctdb_getvnnmap_send(struct ctdb_connection *ctdb,
478 ctdb_callback_t callback,
481 return new_ctdb_control_request(ctdb, CTDB_CONTROL_GETVNNMAP,
483 NULL, 0, callback, private_data);