On 09/04/2012 12:10 PM, Osier Yang wrote:
The RPC generator doesn't support returning list of object yet,
this patch
do the work manually.
* daemon/remote.c:
Implemente the server side handler remoteDispatchConnectListAllInterfaces.
* src/remote/remote_driver.c:
Add remote driver handler remoteConnectListAllInterfaces.
* src/remote/remote_protocol.x:
New RPC procedure REMOTE_PROC_CONNECT_LIST_ALL_INTERFACES and
structs to represent the args and ret for it.
* src/remote_protocol-structs: Likewise.
---
daemon/remote.c | 54 +++++++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 64 ++++++++++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 13 ++++++++-
src/remote_protocol-structs | 12 ++++++++
4 files changed, 142 insertions(+), 1 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index dba51a7..fe2f9dd 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -4265,6 +4265,60 @@ cleanup:
return rv;
}
+static int
+remoteDispatchConnectListAllInterfaces(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_connect_list_all_interfaces_args *args,
+ remote_connect_list_all_interfaces_ret *ret)
+{
+ virInterfacePtr *ifaces = NULL;
+ int nifaces = 0;
+ int i;
+ int rv = -1;
+ struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+
+ if (!priv->conn) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not
open"));
+ goto cleanup;
+ }
+
+ if ((nifaces = virConnectListAllInterfaces(priv->conn,
+ args->need_results ? &ifaces :
NULL,
+ args->flags)) < 0)
+ goto cleanup;
+
+ if (ifaces && nifaces) {
+ if (VIR_ALLOC_N(ret->ifaces.ifaces_val, nifaces) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ret->ifaces.ifaces_len = nifaces;
+
+ for (i = 0; i < nifaces; i++)
+ make_nonnull_interface(ret->ifaces.ifaces_val + i, ifaces[i]);
+ } else {
+ ret->ifaces.ifaces_len = 0;
+ ret->ifaces.ifaces_val = NULL;
+ }
+
+ ret->ret = nifaces;
+
+ rv = 0;
+
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ if (ifaces) {
+ for (i = 0; i < nifaces; i++)
+ virInterfaceFree(ifaces[i]);
+ VIR_FREE(ifaces);
+ }
+ return rv;
+}
+
/*----- Helpers. -----*/
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 56e50a6..5c97061 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -2781,6 +2781,69 @@ done:
return rv;
}
+static int
+remoteConnectListAllInterfaces(virConnectPtr conn,
+ virInterfacePtr **ifaces,
+ unsigned int flags)
+{
+ int rv = -1;
+ int i;
+ virInterfacePtr *tmp_ifaces = NULL;
+ remote_connect_list_all_interfaces_args args;
+ remote_connect_list_all_interfaces_ret ret;
+
+ struct private_data *priv = conn->privateData;
+
+ remoteDriverLock(priv);
+
+ args.need_results = !!ifaces;
+ args.flags = flags;
+
+ memset(&ret, 0, sizeof(ret));
+ if (call(conn,
+ priv,
+ 0,
+ REMOTE_PROC_CONNECT_LIST_ALL_INTERFACES,
+ (xdrproc_t) xdr_remote_connect_list_all_interfaces_args,
+ (char *) &args,
+ (xdrproc_t) xdr_remote_connect_list_all_interfaces_ret,
+ (char *) &ret) == -1)
+ goto done;
+
+ if (ifaces) {
+ if (VIR_ALLOC_N(tmp_ifaces, ret.ifaces.ifaces_len + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ for (i = 0; i < ret.ifaces.ifaces_len; i++) {
+ tmp_ifaces[i] = get_nonnull_interface (conn, ret.ifaces.ifaces_val[i]);
+ if (!tmp_ifaces[i]) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ *ifaces = tmp_ifaces;
+ tmp_ifaces = NULL;
+ }
+
+ rv = ret.ret;
+
+cleanup:
+ if (tmp_ifaces) {
+ for (i = 0; i < ret.ifaces.ifaces_len; i++)
+ if (tmp_ifaces[i])
+ virInterfaceFree(tmp_ifaces[i]);
+ VIR_FREE(tmp_ifaces);
+ }
I've just noticed that in this case (at least) you put the VIR_FREE(x)
inside the "if (x)" and in some other cases you put it outside. Either
one works, of course, but it would be better to be consistent (just so
those of us with OCD don't start wondering if there's a reason :-)
+
+ xdr_free((xdrproc_t) xdr_remote_connect_list_all_interfaces_ret, (char *)
&ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
/*----------------------------------------------------------------------*/
@@ -5783,6 +5846,7 @@ static virInterfaceDriver interface_driver = {
.listInterfaces = remoteListInterfaces, /* 0.7.2 */
.numOfDefinedInterfaces = remoteNumOfDefinedInterfaces, /* 0.7.2 */
.listDefinedInterfaces = remoteListDefinedInterfaces, /* 0.7.2 */
+ .listAllInterfaces = remoteConnectListAllInterfaces, /* 0.10.0 */
0.10.2
.interfaceLookupByName = remoteInterfaceLookupByName, /* 0.7.2
*/
.interfaceLookupByMACString = remoteInterfaceLookupByMACString, /* 0.7.2 */
.interfaceGetXMLDesc = remoteInterfaceGetXMLDesc, /* 0.7.2 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 12ecfd7..54054af 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2589,6 +2589,16 @@ struct remote_connect_list_all_networks_ret {
unsigned int ret;
};
+struct remote_connect_list_all_interfaces_args {
+ int need_results;
+ unsigned int flags;
+};
+
+struct remote_connect_list_all_interfaces_ret {
+ remote_nonnull_interface ifaces<>;
+ unsigned int ret;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -2922,7 +2932,8 @@ enum remote_procedure {
REMOTE_PROC_CONNECT_LIST_ALL_STORAGE_POOLS = 281, /* skipgen skipgen priority:high
*/
REMOTE_PROC_STORAGE_POOL_LIST_ALL_VOLUMES = 282, /* skipgen skipgen priority:high
*/
- REMOTE_PROC_CONNECT_LIST_ALL_NETWORKS = 283 /* skipgen skipgen priority:high */
+ REMOTE_PROC_CONNECT_LIST_ALL_NETWORKS = 283, /* skipgen skipgen priority:high */
+ REMOTE_PROC_CONNECT_LIST_ALL_INTERFACES = 284 /* skipgen skipgen priority:high */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 45262f8..4e41c67 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2045,6 +2045,17 @@ struct remote_list_all_networks_ret {
} nets;
u_int ret;
};
+struct remote_connect_list_all_interfaces_args {
+ int need_results;
+ u_int flags;
+};
+struct remote_connect_list_all_interfaces_ret {
+ struct {
+ u_int ifaces_len;
+ remote_nonnull_interface * ifaces_val;
+ } pools;
+ u_int ret;
+};
enum remote_procedure {
REMOTE_PROC_OPEN = 1,
REMOTE_PROC_CLOSE = 2,
@@ -2329,4 +2340,5 @@ enum remote_procedure {
REMOTE_PROC_CONNECT_LIST_ALL_STORAGE_POOLS = 281,
REMOTE_PROC_STORAGE_POOL_LIST_ALL_VOLUMES = 282,
REMOTE_PROC_CONNECT_LIST_ALL_NETWORKS = 283,
+ REMOTE_PROC_CONNECT_LIST_ALL_INTERFACES = 284,
};
ACK.