On 13/09/13 05:53, Nehal J Wani wrote:
Implement RPC calls for virNetworkGetDHCPLeases, virNetworkGetDHCPLeasesForMAC
daemon/remote.c
* Define remoteSerializeNetworkDHCPLeases,
remoteDispatchNetworkGetDHCPLeases
* Define remoteDispatchNetworkGetDHCPLeasesForMAC
src/remote/remote_driver.c
* Define remoteNetworkGetDHCPLeases
* Define remoteNetworkGetDHCPLeasesForMAC
src/remote/remote_protocol.x
* New RPC procedure: REMOTE_PROC_NETWORK_GET_DHCP_LEASES
* Define structs remote_network_dhcp_leases, remote_network_get_dhcp_leases_args,
remote_network_get_dhcp_leases_ret
* New RPC procedure: REMOTE_PROC_NETWORK_GET_DHCP_LEASES_FOR_MAC
* Define structs remote_network_dhcp_leases_for_mac, remote_network_get_dhcp_leases_for_mac_args,
remote_network_get_dhcp_leases_for_mac_ret
src/remote_protocol-structs
* New structs added
src/rpc/gendispatch.pl
* Add exception (s/Dhcp/DHCP) for auto-generating names of the remote functions
in ./daemon/remote_dispatch.h
---
daemon/remote.c | 133 ++++++++++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 150 +++++++++++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 50 ++++++++++++++-
src/remote_protocol-structs | 32 +++++++++
src/rpc/gendispatch.pl | 1 +
5 files changed, 365 insertions(+), 1 deletion(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 2aff7c1..de03739 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -5137,7 +5137,140 @@ cleanup:
return rv;
}
+static int
+remoteSerializeNetworkDHCPLeases(virNetworkDHCPLeasesPtr *leases,
+ int nleases,
+ remote_network_get_dhcp_leases_ret *ret)
+{
+ size_t i;
+
+ if (nleases > REMOTE_NETWORK_DHCPLEASES_MAX) {
I think REMOTE_NETWORK_DHCP_LEASES_MAX is better.
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Number of leases is %d, which exceeds max limit: %d"),
+ nleases, REMOTE_NETWORK_DHCPLEASES_MAX);
+ return -1;
+ }
+
+ if (VIR_ALLOC_N(ret->leases.leases_val, nleases) < 0)
+ goto error;
If you "return -1;" here....
+
+ ret->leases.leases_len = nleases;
+
+ for (i = 0; i < nleases; i++) {
+ virNetworkDHCPLeasesPtr lease = leases[i];
+ remote_network_dhcp_lease *lease_ret = &(ret->leases.leases_val[i]);
+ lease_ret->expirytime = lease->expirytime;
+ lease_ret->type = lease->type;
+ lease_ret->prefix = lease->prefix;
+
+ if ((VIR_STRDUP(lease_ret->mac, lease->mac) < 0) ||
+ (VIR_STRDUP(lease_ret->ipaddr, lease->ipaddr) < 0) ||
+ (VIR_STRDUP(lease_ret->hostname, lease->hostname) < 0) ||
+ (VIR_STRDUP(lease_ret->clientid, lease->clientid) < 0))
+ goto error;
+ }
+
+ return 0;
+
+error:
+ if (ret->leases.leases_val) {
then no need for this checking.
+ for (i = 0; i < nleases; i++) {
+ remote_network_dhcp_lease *lease_ret = &(ret->leases.leases_val[i]);
+ virNetworkDHCPLeaseFree((virNetworkDHCPLeasesPtr)lease_ret);
+ }
+ }
+ return -1;
+}
+
+static int
+remoteDispatchNetworkGetDHCPLeases(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_network_get_dhcp_leases_args *args,
+ remote_network_get_dhcp_leases_ret *ret)
+{
+ int rv = -1;
+ struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+ virNetworkDHCPLeasesPtr *leases = NULL;
+ virNetworkPtr net = NULL;
+ int nleases = 0;
+
+ if (!priv->conn) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+ goto cleanup;
+ }
+
+ if (!(net = get_nonnull_network(priv->conn, args->net)))
+ goto cleanup;
+
+ if ((nleases = virNetworkGetDHCPLeases(net, &leases, args->flags)) < 0)
+ goto cleanup;
+
+ if (remoteSerializeNetworkDHCPLeases(leases, nleases, ret) < 0)
+ goto cleanup;
+ rv = nleases;
+
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ if (leases) {
+ size_t i;
+ for (i = 0; i < nleases; i++) {
+ virNetworkDHCPLeaseFree(leases[i]);
+ }
+ }
Network object "net" is leaked. [1]
+ VIR_FREE(leases);
+ return rv;
+}
+
+static int
+remoteDispatchNetworkGetDHCPLeasesForMAC(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_network_get_dhcp_leases_for_mac_args *args,
+ remote_network_get_dhcp_leases_for_mac_ret *ret)
+{
+ int rv = -1;
+ struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+ virNetworkDHCPLeasesPtr *leases = NULL;
+ virNetworkPtr net = NULL;
+ int nleases = 0;
+ const char *mac = NULL;
+
+ if (!priv->conn) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+ goto cleanup;
+ }
+
+ if (!(net = get_nonnull_network(priv->conn, args->net)))
+ goto cleanup;
+
+ mac = args->mac ? *args->mac : NULL;
+
+ if ((nleases = virNetworkGetDHCPLeasesForMAC(net, mac, &leases, args->flags)) < 0)
+ goto cleanup;
+
+ if (remoteSerializeNetworkDHCPLeases(leases, nleases,
+ (remote_network_get_dhcp_leases_ret *)ret) < 0)
+ goto cleanup;
+
+ rv = nleases;
+
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ if (leases) {
+ size_t i;
+ for (i = 0; i < nleases; i++) {
+ virNetworkDHCPLeaseFree(leases[i]);
+ }
+ }
+ VIR_FREE(leases);
Same as [1]
+ return rv;
+}
/*----- Helpers. -----*/
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 62e77a5..693de42 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -6599,6 +6599,154 @@ done:
return rv;
}
+static int
+remoteNetworkGetDHCPLeasesForMAC(virNetworkPtr net,
+ const char *mac,
+ virNetworkDHCPLeasesPtr **leases,
+ unsigned int flags)
+{
+ int rv = -1;
+ size_t i;
+ struct private_data *priv = net->conn->networkPrivateData;
+ remote_network_get_dhcp_leases_for_mac_args args;
+ remote_network_get_dhcp_leases_for_mac_ret ret;
+
+ virNetworkDHCPLeasesPtr *leases_ret;
+ remoteDriverLock(priv);
+
+ make_nonnull_network(&args.net, net);
+ args.mac = mac ? (char **)&mac : NULL;
+ args.flags = flags;
+
+ memset(&ret, 0, sizeof(ret));
+
+ if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_GET_DHCP_LEASES_FOR_MAC,
+ (xdrproc_t)xdr_remote_network_get_dhcp_leases_for_mac_args, (char *)&args,
+ (xdrproc_t)xdr_remote_network_get_dhcp_leases_for_mac_ret, (char *)&ret) == -1) {
+ goto done;
+ }
+
+ if (ret.leases.leases_len > REMOTE_NETWORK_DHCPLEASES_MAX) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Number of leases is %d, which exceeds max limit: %d"),
+ ret.leases.leases_len, REMOTE_NETWORK_DHCPLEASES_MAX);
Likewise, s/DHCPLEASES/DHCP_LEASES/,
+ return -1;
+ goto cleanup;
+ }
+
+ if (ret.leases.leases_len &&
+ VIR_ALLOC_N(leases_ret, ret.leases.leases_len) < 0) {
[2] The API declares the returned array is NULL terminated, but here it
doesn't,
you should allocate one more element for it:
VIR_ALLOC_N(leases_ret, ret.leases.leases_len + 1)
+ goto cleanup;
+ }
+
+ for (i = 0; i < ret.leases.leases_len; i++) {
+ if (VIR_ALLOC(leases_ret[i]) < 0)
+ goto cleanup;
+
+ virNetworkDHCPLeasesPtr lease = leases_ret[i];
+ remote_network_dhcp_lease *lease_ret = &(ret.leases.leases_val[i]);
+ lease->expirytime = lease_ret->expirytime;
+ lease->type = lease_ret->type;
+ lease->prefix = lease_ret->prefix;
+
+ if ((VIR_STRDUP(lease->mac, lease_ret->mac) < 0) ||
+ (VIR_STRDUP(lease->ipaddr, lease_ret->ipaddr) < 0) ||
+ (VIR_STRDUP(lease->hostname, lease_ret->hostname) < 0) ||
+ (VIR_STRDUP(lease->clientid, lease_ret->clientid) < 0))
+ goto cleanup;
+ }
+
+ *leases = leases_ret;
+ leases_ret = NULL;
+ rv = ret.leases.leases_len;
+
+cleanup:
+ if (leases_ret) {
+ for (i = 0; i < ret.leases.leases_len; i++)
+ virNetworkDHCPLeaseFree(leases_ret[i]);
+ }
+ VIR_FREE(leases_ret);
+ xdr_free((xdrproc_t)xdr_remote_network_get_dhcp_leases_for_mac_ret,
+ (char *) &ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+static int
+remoteNetworkGetDHCPLeases(virNetworkPtr net,
+ virNetworkDHCPLeasesPtr **leases,
+ unsigned int flags)
+{
+ int rv = -1;
+ size_t i;
+ struct private_data *priv = net->conn->networkPrivateData;
+ remote_network_get_dhcp_leases_args args;
+ remote_network_get_dhcp_leases_ret ret;
+
+ virNetworkDHCPLeasesPtr *leases_ret;
+ remoteDriverLock(priv);
+
+ make_nonnull_network(&args.net, net);
+ args.flags = flags;
+
+ memset(&ret, 0, sizeof(ret));
+
+ if (call(net->conn, priv, 0, REMOTE_PROC_NETWORK_GET_DHCP_LEASES,
+ (xdrproc_t)xdr_remote_network_get_dhcp_leases_args, (char *)&args,
+ (xdrproc_t)xdr_remote_network_get_dhcp_leases_ret, (char *)&ret) == -1) {
+ goto done;
+ }
+
+ if (ret.leases.leases_len > REMOTE_NETWORK_DHCPLEASES_MAX) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Number of leases is %d, which exceeds max limit: %d"),
+ ret.leases.leases_len, REMOTE_NETWORK_DHCPLEASES_MAX);
s/DHCPLEASES/DHCP_LEASES/,
+ return -1;
+ goto cleanup;
+ }
+
+ if (ret.leases.leases_len &&
+ VIR_ALLOC_N(leases_ret, ret.leases.leases_len) < 0) {
Same problem as [2]
+ goto cleanup;
+ }
+
+ for (i = 0; i < ret.leases.leases_len; i++) {
+ if (VIR_ALLOC(leases_ret[i]) < 0)
+ goto cleanup;
+
+ virNetworkDHCPLeasesPtr lease = leases_ret[i];
+ remote_network_dhcp_lease *lease_ret = &(ret.leases.leases_val[i]);
+ lease->expirytime = lease_ret->expirytime;
+ lease->type = lease_ret->type;
+ lease->prefix = lease_ret->prefix;
+
+ if ((VIR_STRDUP(lease->mac, lease_ret->mac) < 0) ||
+ (VIR_STRDUP(lease->ipaddr, lease_ret->ipaddr) < 0) ||
+ (VIR_STRDUP(lease->hostname, lease_ret->hostname) < 0) ||
+ (VIR_STRDUP(lease->clientid, lease_ret->clientid) < 0))
+ goto cleanup;
+ }
+
+ *leases = leases_ret;
+ leases_ret = NULL;
+ rv = ret.leases.leases_len;
+
+cleanup:
+ if (leases_ret) {
+ for (i = 0; i < ret.leases.leases_len; i++)
+ virNetworkDHCPLeaseFree(leases_ret[i]);
+ }
+ VIR_FREE(leases_ret);
+ xdr_free((xdrproc_t)xdr_remote_network_get_dhcp_leases_ret,
+ (char *) &ret);
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
static void
remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event)
{
@@ -6958,6 +7106,8 @@ static virNetworkDriver network_driver = {
.networkSetAutostart = remoteNetworkSetAutostart, /* 0.3.0 */
.networkIsActive = remoteNetworkIsActive, /* 0.7.3 */
.networkIsPersistent = remoteNetworkIsPersistent, /* 0.7.3 */
+ .networkGetDHCPLeases = remoteNetworkGetDHCPLeases, /* 1.1.3 */
+ .networkGetDHCPLeasesForMAC = remoteNetworkGetDHCPLeasesForMAC, /* 1.1.3 */
};
static virInterfaceDriver interface_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 85ad9ba..c455038 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -232,6 +232,11 @@ const REMOTE_DOMAIN_MIGRATE_PARAM_LIST_MAX = 64;
/* Upper limit on number of job stats */
const REMOTE_DOMAIN_JOB_STATS_MAX = 16;
+/*
+ * Upper limit on the maximum number of leases in one lease file
+ */
+const REMOTE_NETWORK_DHCPLEASES_MAX = 32768;
+
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@@ -2835,6 +2840,35 @@ struct remote_domain_event_device_removed_msg {
remote_nonnull_string devAlias;
};
+struct remote_network_dhcp_lease {
+ hyper expirytime;
+ remote_nonnull_string mac;
+ remote_nonnull_string ipaddr;
+ remote_nonnull_string hostname;
+ remote_nonnull_string clientid;
+ int type;
+ unsigned int prefix;
+};
+
+struct remote_network_get_dhcp_leases_args {
+ remote_nonnull_network net;
+ unsigned int flags;
+};
+
+struct remote_network_get_dhcp_leases_ret {
+ remote_network_dhcp_lease leases<REMOTE_NETWORK_DHCPLEASES_MAX>;
Likewise.
+};
+
+struct remote_network_get_dhcp_leases_for_mac_args {
+ remote_nonnull_network net;
+ remote_string mac;
+ unsigned int flags;
+};
+
+struct remote_network_get_dhcp_leases_for_mac_ret {
+ remote_network_dhcp_lease leases<REMOTE_NETWORK_DHCPLEASES_MAX>;
Likewise.
Osier
--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list