diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2011-12-06 13:11:13 +1100 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2011-12-06 13:12:18 +1100 |
commit | 609149bdc82488b236c221d80aa7d517077fb950 (patch) | |
tree | 7fa28a5fafeb01e3ab2311eb3e34e516a0bca690 | |
parent | 1ed5288c38c7ebcf70fcbe6c43ca6b546ca67f7e (diff) | |
download | samba-609149bdc82488b236c221d80aa7d517077fb950.tar.gz samba-609149bdc82488b236c221d80aa7d517077fb950.tar.xz samba-609149bdc82488b236c221d80aa7d517077fb950.zip |
LibCTDB: Add support for the 'get interfaces' control and update the ctdb tool to use this interface
(This used to be ctdb commit 77dc0c7351071243d9096d3607d7499c82f46ec0)
-rw-r--r-- | ctdb/include/ctdb.h | 56 | ||||
-rw-r--r-- | ctdb/include/ctdb_private.h | 6 | ||||
-rw-r--r-- | ctdb/include/ctdb_protocol.h | 19 | ||||
-rw-r--r-- | ctdb/libctdb/control.c | 71 | ||||
-rw-r--r-- | ctdb/libctdb/sync.c | 20 | ||||
-rw-r--r-- | ctdb/tools/ctdb.c | 24 |
6 files changed, 176 insertions, 20 deletions
diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index aeab615b44..795ff5c18c 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -613,6 +613,41 @@ bool ctdb_getnodemap_recv(struct ctdb_connection *ctdb, struct ctdb_request *req, struct ctdb_node_map **nodemap); /** + * ctdb_getifaces_send - read the list of interfaces 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_getifaces_send(struct ctdb_connection *ctdb, + uint32_t destnode, + ctdb_callback_t callback, + void *cbdata); +/** + * ctdb_getifaces_recv - read an ctdb_getifaces reply from ctdbd + * @ctdb: the ctdb_connection from ctdb_connect. + * @req: the completed request. + * @ifaces: the list of interfaces + * + * This returns false if something went wrong. + * If the command failed, it guarantees to set ifaces to NULL. + * A non-NULL value for ifaces means the command was successful. + * + * A non-NULL value of the ifaces must be release released/freed + * by ctdb_free_ifaces(). + */ +bool ctdb_getifaces_recv(struct ctdb_connection *ctdb, + struct ctdb_request *req, struct ctdb_ifaces_list **ifaces); + +/* Free a datastructure returned by ctdb_getifaces[_recv] */ +void ctdb_free_ifaces(struct ctdb_ifaces_list *ifaces); + +/** * ctdb_getpublicips_send - read the public ip list from a node. * @ctdb: the ctdb_connection from ctdb_connect. * @destnode: the destination node (see below) @@ -898,6 +933,23 @@ bool ctdb_getrecmode(struct ctdb_connection *ctdb, bool ctdb_getnodemap(struct ctdb_connection *ctdb, uint32_t destnode, struct ctdb_node_map **nodemap); +/** + * ctdb_getifaces - read the list of interfaces from a node (synchronous) + * @ctdb: the ctdb_connection from ctdb_connect. + * @destnode: the destination node (see below) + * @ifaces: a pointer to the ifaces 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 *ifaces on success. + * A non-NULL value of the ifaces must be release released/freed + * by ctdb_free_ifaces(). + */ +bool ctdb_getifaces(struct ctdb_connection *ctdb, + uint32_t destnode, struct ctdb_ifaces_list **ifaces); + /* * This function is used to release/free the nodemap structure returned * by ctdb_getnodemap() and ctdb_getnodemap_recv() @@ -1011,4 +1063,8 @@ void ctdb_free_publicips(struct ctdb_all_public_ips *ips); ctdb_getdbseqnum_send((ctdb), (destnode), (dbid), \ ctdb_sendcb((cb), (cbdata)), (cbdata)) +#define ctdb_getifaces_send(ctdb, destnode, cb, cbdata) \ + ctdb_getifaces_send((ctdb), (destnode), \ + ctdb_sendcb((cb), (cbdata)), (cbdata)) + #endif diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 5ce32a10f0..9e5e188c49 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -1079,12 +1079,6 @@ int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips); -#ifdef IFNAMSIZ -#define CTDB_IFACE_SIZE IFNAMSIZ -#else -#define CTDB_IFACE_SIZE 16 -#endif - struct ctdb_control_iface_info { char name[CTDB_IFACE_SIZE+2]; uint16_t link_state; diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h index c71bafaaeb..d96f565eb8 100644 --- a/ctdb/include/ctdb_protocol.h +++ b/ctdb/include/ctdb_protocol.h @@ -654,5 +654,24 @@ struct ctdb_statistics_wire { struct ctdb_statistics stats[1]; }; +/* + * wire format for interface list + */ +#ifdef IFNAMSIZ +#define CTDB_IFACE_SIZE IFNAMSIZ +#else +#define CTDB_IFACE_SIZE 16 +#endif + +struct ctdb_iface_info { + char name[CTDB_IFACE_SIZE+2]; + uint16_t link_state; + uint32_t references; +}; + +struct ctdb_ifaces_list { + uint32_t num; + struct ctdb_iface_info ifaces[1]; +}; #endif diff --git a/ctdb/libctdb/control.c b/ctdb/libctdb/control.c index 419238101c..9beb49f9c2 100644 --- a/ctdb/libctdb/control.c +++ b/ctdb/libctdb/control.c @@ -29,6 +29,7 @@ #undef ctdb_getnodemap_send #undef ctdb_getpublicips_send #undef ctdb_getdbseqnum_send +#undef ctdb_getifaces_send bool ctdb_getrecmaster_recv(struct ctdb_connection *ctdb, struct ctdb_request *req, uint32_t *recmaster) @@ -284,3 +285,73 @@ ctdb_check_message_handlers_send(struct ctdb_connection *ctdb, 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); +} + diff --git a/ctdb/libctdb/sync.c b/ctdb/libctdb/sync.c index 6696283f04..9567d9695a 100644 --- a/ctdb/libctdb/sync.c +++ b/ctdb/libctdb/sync.c @@ -280,3 +280,23 @@ bool ctdb_getdbseqnum(struct ctdb_connection *ctdb, } return ret; } + +bool ctdb_getifaces(struct ctdb_connection *ctdb, + uint32_t destnode, struct ctdb_ifaces_list **ifaces) +{ + struct ctdb_request *req; + bool done = false; + bool ret = false; + + *ifaces = NULL; + + req = synchronous(ctdb, + ctdb_getifaces_send(ctdb, destnode, set, &done), + &done); + if (req != NULL) { + ret = ctdb_getifaces_recv(ctdb, req, ifaces); + ctdb_request_free(req); + } + return ret; +} + diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c index 5fd6307672..a356c28c47 100644 --- a/ctdb/tools/ctdb.c +++ b/ctdb/tools/ctdb.c @@ -640,11 +640,11 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv continue; } if (nodemap->nodes[i].flags == 0) { - struct ctdb_control_get_ifaces *ifaces; + struct ctdb_ifaces_list *ifaces; - ret = ctdb_ctrl_get_ifaces(ctdb, TIMELIMIT(), - nodemap->nodes[i].pnn, - ctdb, &ifaces); + ret = ctdb_getifaces(ctdb_connection, + nodemap->nodes[i].pnn, + &ifaces); if (ret == 0) { for (j=0; j < ifaces->num; j++) { if (ifaces->ifaces[j].link_state != 0) { @@ -653,7 +653,7 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv partially_online = 1; break; } - talloc_free(ifaces); + ctdb_free_ifaces(ifaces); } } printf(":%d:%s:%d:%d:%d:%d:%d:%d:%d:%c:\n", nodemap->nodes[i].pnn, @@ -2311,18 +2311,14 @@ static int control_ipinfo(struct ctdb_context *ctdb, int argc, const char **argv */ static int control_ifaces(struct ctdb_context *ctdb, int argc, const char **argv) { - int i, ret; - TALLOC_CTX *tmp_ctx = talloc_new(ctdb); - struct ctdb_control_get_ifaces *ifaces; + int i; + struct ctdb_ifaces_list *ifaces; /* read the public ip list from this node */ - ret = ctdb_ctrl_get_ifaces(ctdb, TIMELIMIT(), options.pnn, - tmp_ctx, &ifaces); - if (ret != 0) { + if (!ctdb_getifaces(ctdb_connection, options.pnn, &ifaces)) { DEBUG(DEBUG_ERR, ("Unable to get interfaces from node %u\n", options.pnn)); - talloc_free(tmp_ctx); - return ret; + return -1; } if (options.machinereadable){ @@ -2345,7 +2341,7 @@ static int control_ifaces(struct ctdb_context *ctdb, int argc, const char **argv } } - talloc_free(tmp_ctx); + ctdb_free_ifaces(ifaces); return 0; } |