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:
parent
1ed5288c38
commit
609149bdc8
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user