The branch, master has been updated via 0f15a2c65db8f8b4ac0d5ad2755b9aa3c2a8b279 (commit) via 77dc0c7351071243d9096d3607d7499c82f46ec0 (commit) from 00212e5c7dd229e7f8975a165d5ab8875d4917cc (commit)
http://gitweb.samba.org/?p=ctdb.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 0f15a2c65db8f8b4ac0d5ad2755b9aa3c2a8b279 Author: Ronnie Sahlberg <ronniesahlb...@gmail.com> Date: Tue Dec 6 13:15:41 2011 +1100 Return the peer_pid properly to the caller commit 77dc0c7351071243d9096d3607d7499c82f46ec0 Author: Ronnie Sahlberg <ronniesahlb...@gmail.com> Date: Tue Dec 6 13:11:13 2011 +1100 LibCTDB: Add support for the 'get interfaces' control and update the ctdb tool to use this interface ----------------------------------------------------------------------- Summary of changes: common/system_aix.c | 2 +- common/system_linux.c | 2 +- include/ctdb.h | 56 +++++++++++++++++++++++++++++++++++++ include/ctdb_private.h | 6 ---- include/ctdb_protocol.h | 19 ++++++++++++ libctdb/control.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ libctdb/sync.c | 20 +++++++++++++ tools/ctdb.c | 24 ++++++--------- 8 files changed, 178 insertions(+), 22 deletions(-) Changeset truncated at 500 lines: diff --git a/common/system_aix.c b/common/system_aix.c index c17598a..388e943 100644 --- a/common/system_aix.c +++ b/common/system_aix.c @@ -368,7 +368,7 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) socklen_t crl = sizeof(struct peercred_struct); int ret; if ((ret = getsockopt(fd, SOL_SOCKET, SO_PEERID, &cr, &crl) == 0)) { - peer_pid = cr.pid; + *peer_pid = cr.pid; } return ret; } diff --git a/common/system_linux.c b/common/system_linux.c index cb26dcd..464daef 100644 --- a/common/system_linux.c +++ b/common/system_linux.c @@ -570,7 +570,7 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid) socklen_t crl = sizeof(struct ucred); int ret; if ((ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crl) == 0)) { - peer_pid = cr.pid; + *peer_pid = cr.pid; } return ret; } diff --git a/include/ctdb.h b/include/ctdb.h index aeab615..795ff5c 100644 --- a/include/ctdb.h +++ b/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/include/ctdb_private.h b/include/ctdb_private.h index 5ce32a1..9e5e188 100644 --- a/include/ctdb_private.h +++ b/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/include/ctdb_protocol.h b/include/ctdb_protocol.h index c71bafa..d96f565 100644 --- a/include/ctdb_protocol.h +++ b/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/libctdb/control.c b/libctdb/control.c index 4192381..9beb49f 100644 --- a/libctdb/control.c +++ b/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/libctdb/sync.c b/libctdb/sync.c index 6696283..9567d96 100644 --- a/libctdb/sync.c +++ b/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/tools/ctdb.c b/tools/ctdb.c index 5fd6307..a356c28 100644 --- a/tools/ctdb.c +++ b/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; } -- CTDB repository