You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <sys/time.h>
+#include <sys/socket.h>
#include <string.h>
#include <ctdb.h>
#include <ctdb_protocol.h>
#undef ctdb_getrecmaster_send
#undef ctdb_getrecmode_send
#undef ctdb_getpnn_send
+#undef ctdb_getdbstat_send
+#undef ctdb_check_message_handlers_send
#undef ctdb_getnodemap_send
#undef ctdb_getpublicips_send
+#undef ctdb_getdbseqnum_send
+#undef ctdb_getifaces_send
+#undef ctdb_getvnnmap_send
+#undef ctdb_getcapabilities_send
bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb,
struct ctdb_request *req, uint32_t *recmaster)
DEBUG(ctdb, LOG_ERR, "ctdb_getrecmaster_recv: status -1");
return false;
}
+ /* Note: data is stashed in status - see ctdb_control_dispatch() */
*recmaster = reply->status;
return true;
}
DEBUG(ctdb, LOG_ERR, "ctdb_getrecmode_recv: status -1");
return false;
}
+ /* Note: data is stashed in status - see ctdb_control_dispatch() */
*recmode = reply->status;
return true;
}
DEBUG(ctdb, LOG_ERR, "ctdb_getpnn_recv: status -1");
return false;
}
+ /* Note: data is stashed in status - see ctdb_control_dispatch() */
*pnn = reply->status;
return true;
}
NULL, 0, callback, private_data);
}
+bool ctdb_getdbstat_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req,
+ struct ctdb_db_statistics **stat)
+{
+ struct ctdb_reply_control *reply;
+ struct ctdb_db_statistics *s, *wire;
+ int i;
+ char *ptr;
+
+ reply = unpack_reply_control(req, CTDB_CONTROL_GET_DB_STATISTICS);
+ if (!reply) {
+ return false;
+ }
+ if (reply->status == -1) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getpnn_recv: status -1");
+ return false;
+ }
+ if (reply->datalen < offsetof(struct ctdb_db_statistics, hot_keys_wire)) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getdbstat_recv: returned data is %d bytes but should be >= %d", reply->datalen, (int)sizeof(struct ctdb_db_statistics));
+ return false;
+ }
+
+ wire = (struct ctdb_db_statistics *)reply->data;
+
+ s = malloc(sizeof(struct ctdb_db_statistics));
+ if (!s) {
+ return false;
+ }
+
+ *s = *wire;
+ ptr = &wire->hot_keys_wire[0];
+ for (i = 0; i < wire->num_hot_keys; i++) {
+ s->hot_keys[i].key.dptr = malloc(s->hot_keys[i].key.dsize);
+ memcpy(s->hot_keys[i].key.dptr, ptr, s->hot_keys[i].key.dsize);
+ ptr += s->hot_keys[i].key.dsize;
+ }
+
+ *stat = s;
+
+ return true;
+}
+
+struct ctdb_request *ctdb_getdbstat_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ uint32_t db_id,
+ ctdb_callback_t callback,
+ void *private_data)
+{
+ uint32_t indata = db_id;
+
+ return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_DB_STATISTICS, destnode,
+ &indata, sizeof(indata), callback, private_data);
+}
+
+void ctdb_free_dbstat(struct ctdb_db_statistics *stat)
+{
+ int i;
+
+ if (stat == NULL) {
+ return;
+ }
+
+ for (i = 0; i < stat->num_hot_keys; i++) {
+ if (stat->hot_keys[i].key.dptr != NULL) {
+ free(stat->hot_keys[i].key.dptr);
+ }
+ }
+
+ free(stat);
+}
+
bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb,
struct ctdb_request *req, struct ctdb_node_map **nodemap)
{
}
free(ips);
}
+
+bool ctdb_getdbseqnum_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req, uint64_t *seqnum)
+{
+ struct ctdb_reply_control *reply;
+
+ reply = unpack_reply_control(req, CTDB_CONTROL_GET_DB_SEQNUM);
+ if (!reply) {
+ return false;
+ }
+ if (reply->status == -1) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum_recv: status -1");
+ return false;
+ }
+
+ if (reply->datalen != sizeof(uint64_t)) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getdbseqnum wrong size of data was %d but expected %d bytes", reply->datalen, (int)sizeof(uint64_t));
+ return false;
+ }
+
+ *seqnum = *((uint64_t *)reply->data);
+
+ return true;
+}
+
+struct ctdb_request *ctdb_getdbseqnum_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ uint32_t dbid,
+ ctdb_callback_t callback,
+ void *private_data)
+{
+ uint64_t indata;
+
+ *((uint32_t *)&indata) = dbid;
+
+ return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_DB_SEQNUM,
+ destnode, &indata, sizeof(uint64_t),
+ callback, private_data);
+}
+
+bool ctdb_check_message_handlers_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req,
+ uint32_t num, uint8_t *result)
+{
+ struct ctdb_reply_control *reply;
+ int i, count;
+
+ reply = unpack_reply_control(req, CTDB_CONTROL_CHECK_SRVIDS);
+ if (!reply) {
+ return false;
+ }
+ if (reply->status == -1) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_check_message_handlers_recv: status -1");
+ return false;
+ }
+
+ count = (num + 7) / 8;
+ if (count != reply->datalen) {
+ 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);
+ return false;
+ }
+
+ for (i = 0; i < num; i++) {
+ result[i] = !!(reply->data[i / 8] & (1 << (i % 8)));
+ }
+
+ return true;
+}
+
+struct ctdb_request *
+ctdb_check_message_handlers_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ uint32_t num,
+ uint64_t *mhs,
+ ctdb_callback_t callback,
+ void *private_data)
+{
+ return new_ctdb_control_request(ctdb, CTDB_CONTROL_CHECK_SRVIDS,
+ destnode,
+ mhs, num * sizeof(uint64_t) ,
+ callback, private_data);
+}
+
+
+bool ctdb_getifaces_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req,
+ struct ctdb_ifaces_list **ifaces)
+{
+ struct ctdb_reply_control *reply;
+ struct ctdb_ifaces_list *ifc;
+ int i, len;
+
+ *ifaces = NULL;
+ reply = unpack_reply_control(req, CTDB_CONTROL_GET_IFACES);
+ if (!reply) {
+ return false;
+ }
+ if (reply->status == -1) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: status -1");
+ return false;
+ }
+ if (reply->datalen == 0) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: returned data is 0 bytes");
+ return false;
+ }
+
+ len = offsetof(struct ctdb_ifaces_list, ifaces);
+ if (len > reply->datalen) {
+ 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));
+ return false;
+ }
+
+ ifc = (struct ctdb_ifaces_list *)(reply->data);
+ len += ifc->num * sizeof(struct ctdb_iface_info);
+
+ if (len != reply->datalen) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: returned data is %d bytes but should be %d", reply->datalen, len);
+ return false;
+ }
+
+ ifc = malloc(reply->datalen);
+ if (ifc == NULL) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getifaces_recv: failed to malloc buffer");
+ return false;
+ }
+ memcpy(ifc, reply->data, reply->datalen);
+
+ /* make sure we null terminate the returned strings */
+ for (i = 0; i < ifc->num; i++) {
+ ifc->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
+ }
+
+ *ifaces = ifc;
+
+ return true;
+}
+
+void ctdb_free_ifaces(struct ctdb_ifaces_list *ifaces)
+{
+ free(ifaces);
+}
+
+struct ctdb_request *ctdb_getifaces_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ ctdb_callback_t callback,
+ void *private_data)
+{
+ return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_IFACES,
+ destnode,
+ NULL, 0, callback, private_data);
+}
+
+bool ctdb_getvnnmap_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req,
+ struct ctdb_vnn_map **vnnmap)
+{
+ struct ctdb_reply_control *reply;
+ struct ctdb_vnn_map_wire *map;
+ struct ctdb_vnn_map *tmap;
+ int len;
+
+ *vnnmap = NULL;
+ reply = unpack_reply_control(req, CTDB_CONTROL_GETVNNMAP);
+ if (!reply) {
+ return false;
+ }
+ if (reply->status == -1) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: status -1");
+ return false;
+ }
+ if (reply->datalen == 0) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: returned data is 0 bytes");
+ return false;
+ }
+
+ len = offsetof(struct ctdb_vnn_map_wire, map);
+ if (len > reply->datalen) {
+ 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));
+ return false;
+ }
+
+ map = (struct ctdb_vnn_map_wire *)(reply->data);
+ len += map->size * sizeof(uint32_t);
+
+ if (len != reply->datalen) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: returned data is %d bytes but should be %d", reply->datalen, len);
+ return false;
+ }
+
+ tmap = malloc(sizeof(struct ctdb_vnn_map));
+ if (tmap == NULL) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: failed to malloc buffer");
+ return false;
+ }
+
+ tmap->generation = map->generation;
+ tmap->size = map->size;
+ tmap->map = malloc(sizeof(uint32_t) * map->size);
+ if (tmap->map == NULL) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getvnnmap_recv: failed to malloc buffer");
+ free(tmap);
+ return false;
+ }
+
+ memcpy(tmap->map, map->map, sizeof(uint32_t)*map->size);
+
+ *vnnmap = tmap;
+
+ return true;
+}
+
+void ctdb_free_vnnmap(struct ctdb_vnn_map *vnnmap)
+{
+ free(vnnmap->map);
+ free(vnnmap);
+}
+
+struct ctdb_request *ctdb_getvnnmap_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ ctdb_callback_t callback,
+ void *private_data)
+{
+ return new_ctdb_control_request(ctdb, CTDB_CONTROL_GETVNNMAP,
+ destnode,
+ NULL, 0, callback, private_data);
+}
+
+bool ctdb_getcapabilities_recv(struct ctdb_connection *ctdb,
+ struct ctdb_request *req, uint32_t *capabilities)
+{
+ struct ctdb_reply_control *reply;
+
+ reply = unpack_reply_control(req, CTDB_CONTROL_GET_CAPABILITIES);
+ if (!reply) {
+ return false;
+ }
+ if (reply->status == -1) {
+ DEBUG(ctdb, LOG_ERR, "ctdb_getcapabilities_recv: status -1");
+ return false;
+ }
+ *capabilities = *((uint32_t *)reply->data);
+ return true;
+}
+
+struct ctdb_request *ctdb_getcapabilities_send(struct ctdb_connection *ctdb,
+ uint32_t destnode,
+ ctdb_callback_t callback,
+ void *private_data)
+{
+ return new_ctdb_control_request(ctdb, CTDB_CONTROL_GET_CAPABILITIES,
+ destnode,
+ NULL, 0, callback, private_data);
+}
+