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.
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()
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
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;
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
#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)
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);
+}
+
}
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;
+}
+
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) {
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,
*/
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){
}
}
- talloc_free(tmp_ctx);
+ ctdb_free_ifaces(ifaces);
return 0;
}