1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-19 18:50:24 +03:00

LibCTDB: Add support for the 'get interfaces' control and update the ctdb tool to use this interface

(This used to be ctdb commit 77dc0c7351071243d9096d3607d7499c82f46ec0)
This commit is contained in:
Ronnie Sahlberg 2011-12-06 13:11:13 +11:00
parent 1ed5288c38
commit 609149bdc8
6 changed files with 176 additions and 20 deletions

View File

@ -612,6 +612,41 @@ ctdb_getnodemap_send(struct ctdb_connection *ctdb,
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.
@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}