From ed8a8ee966ee84a45832492be56cfb36f611037e Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Mon, 12 Dec 2011 16:48:10 +1100 Subject: [PATCH] libctdb - add ctdb_getvnnmap() Signed-off-by: Martin Schwenke (This used to be ctdb commit f6039eaece4224b866a98dd49010f278a7b3f015) --- ctdb/include/ctdb.h | 59 ++++++++++++++++++++++++++++ ctdb/include/ctdb_private.h | 20 ---------- ctdb/include/ctdb_protocol.h | 18 +++++++++ ctdb/libctdb/control.c | 76 ++++++++++++++++++++++++++++++++++++ ctdb/libctdb/sync.c | 19 +++++++++ 5 files changed, 172 insertions(+), 20 deletions(-) diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index 795ff5c18cc..8dbdd47e1e2 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -743,6 +743,38 @@ bool ctdb_getrecmode_recv(struct ctdb_connection *ctdb, struct ctdb_request *handle, uint32_t *recmode); +/** + * ctdb_getvnnmap_send - read the vnn map from a node. + * @ctdb: the ctdb_connection from ctdb_connect. + * @destnode: the destination node (see below) + * @callback: the callback when ctdb replies to our message (typesafe) + * @cbdata: the argument to callback() + * + * There are several special values for destnode, detailed in + * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the + * local ctdbd. + */ +struct ctdb_request * +ctdb_getvnnmap_send(struct ctdb_connection *ctdb, + uint32_t destnode, + ctdb_callback_t callback, + void *cbdata); +/** + * ctdb_getvnnmap_recv - read an ctdb_getvnnmap reply from ctdbd + * @ctdb: the ctdb_connection from ctdb_connect. + * @req: the completed request. + * @vnnmap: the list of interfaces + * + * This returns false if something went wrong. + * If the command failed, it guarantees to set vnnmap to NULL. + * A non-NULL value for vnnmap means the command was successful. + * + * A non-NULL value of the vnnmap must be released/freed + * by ctdb_free_vnnmap(). + */ +bool ctdb_getvnnmap_recv(struct ctdb_connection *ctdb, + struct ctdb_request *req, struct ctdb_vnn_map **vnnmap); + /** * ctdb_cancel - cancel an uncompleted request * @ctdb: the ctdb_connection from ctdb_connect. @@ -989,6 +1021,29 @@ bool ctdb_getpublicips(struct ctdb_connection *ctdb, void ctdb_free_publicips(struct ctdb_all_public_ips *ips); +/** + * ctdb_getvnnmap - read the vnn map from a node (synchronous) + * @ctdb: the ctdb_connection from ctdb_connect. + * @destnode: the destination node (see below) + * @vnnmap: a pointer to the vnnmap to fill in + * + * There are several special values for destnode, detailed in + * ctdb_protocol.h, particularly CTDB_CURRENT_NODE which means the + * local ctdbd. + * + * Returns true and fills in *vnnmap on success. + * A non-NULL value of the vnnmap must be released/freed + * by ctdb_free_vnnmap(). + */ +bool ctdb_getvnnmap(struct ctdb_connection *ctdb, + uint32_t destnode, struct ctdb_vnn_map **vnnmap); + +/* + * This function is used to release/free the vnnmap structure returned + * by ctdb_getvnnmap() and ctdb_getvnnmap_recv() + */ +void ctdb_free_vnnmap(struct ctdb_vnn_map *vnnmap); + /* These ugly macro wrappers make the callbacks typesafe. */ #include #define ctdb_sendcb(cb, cbdata) \ @@ -1067,4 +1122,8 @@ void ctdb_free_publicips(struct ctdb_all_public_ips *ips); ctdb_getifaces_send((ctdb), (destnode), \ ctdb_sendcb((cb), (cbdata)), (cbdata)) +#define ctdb_getvnnmap_send(ctdb, destnode, cb, cbdata) \ + ctdb_getvnnmap_send((ctdb), (destnode), \ + ctdb_sendcb((cb), (cbdata)), (cbdata)) + #endif diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 92d498aaf7e..f58356fbe74 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -363,26 +363,6 @@ struct ctdb_daemon_data { - - -#define INVALID_GENERATION 1 -/* table that contains the mapping between a hash value and lmaster - */ -struct ctdb_vnn_map { - uint32_t generation; - uint32_t size; - uint32_t *map; -}; - -/* - a wire representation of the vnn map - */ -struct ctdb_vnn_map_wire { - uint32_t generation; - uint32_t size; - uint32_t map[1]; -}; - /* a structure that contains the elements required for the write record control */ diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h index 70197d94bd4..0b3245dc882 100644 --- a/ctdb/include/ctdb_protocol.h +++ b/ctdb/include/ctdb_protocol.h @@ -676,4 +676,22 @@ struct ctdb_ifaces_list { struct ctdb_iface_info ifaces[1]; }; +#define INVALID_GENERATION 1 +/* table that contains the mapping between a hash value and lmaster + */ +struct ctdb_vnn_map { + uint32_t generation; + uint32_t size; + uint32_t *map; +}; + +/* + a wire representation of the vnn map + */ +struct ctdb_vnn_map_wire { + uint32_t generation; + uint32_t size; + uint32_t map[1]; +}; + #endif diff --git a/ctdb/libctdb/control.c b/ctdb/libctdb/control.c index 9beb49f9c2e..ba22444ee54 100644 --- a/ctdb/libctdb/control.c +++ b/ctdb/libctdb/control.c @@ -30,6 +30,7 @@ #undef ctdb_getpublicips_send #undef ctdb_getdbseqnum_send #undef ctdb_getifaces_send +#undef ctdb_getvnnmap_send bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb, struct ctdb_request *req, uint32_t *recmaster) @@ -355,3 +356,78 @@ struct ctdb_request *ctdb_getifaces_send(struct ctdb_connection *ctdb, 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); +} + diff --git a/ctdb/libctdb/sync.c b/ctdb/libctdb/sync.c index 9567d9695ad..f2b69570785 100644 --- a/ctdb/libctdb/sync.c +++ b/ctdb/libctdb/sync.c @@ -300,3 +300,22 @@ bool ctdb_getifaces(struct ctdb_connection *ctdb, return ret; } +bool ctdb_getvnnmap(struct ctdb_connection *ctdb, + uint32_t destnode, struct ctdb_vnn_map **vnnmap) +{ + struct ctdb_request *req; + bool done = false; + bool ret = false; + + *vnnmap = NULL; + + req = synchronous(ctdb, + ctdb_getvnnmap_send(ctdb, destnode, set, &done), + &done); + if (req != NULL) { + ret = ctdb_getvnnmap_recv(ctdb, req, vnnmap); + ctdb_request_free(req); + } + return ret; +} +