[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/4] net-dhcp-leases: Implement the remote protocol



Implement RPC calls for virNetworkGetDHCPLeases, virNetworkGetDHCPLeaseForMAC

daemon/remote.c
   * Define remoteSerializeNetworkDHCPLeases,
            remoteDispatchNetworkGetDHCPLeases
   * Define remoteDispatchNetworkGetDHCPLeaseForMAC

src/remote/remote_driver.c
   * Define remoteNetworkGetDHCPLeases
   * Define remoteNetworkGetDHCPLeaseForMAC

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_LEASE_FOR_MAC
   * Define structs remote_network_dhcp_lease_for_mac, remote_network_get_dhcp_lease_for_mac_args,
                    remote_network_get_dhcp_lease_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              | 128 +++++++++++++++++++++++++++++++++++++++++++
 src/remote/remote_driver.c   | 117 +++++++++++++++++++++++++++++++++++++++
 src/remote/remote_protocol.x |  48 +++++++++++++++-
 src/remote_protocol-structs  |  27 +++++++++
 src/rpc/gendispatch.pl       |   1 +
 5 files changed, 320 insertions(+), 1 deletion(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 2aff7c1..13be327 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -5137,7 +5137,135 @@ 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) {
+        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;
+
+    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;
+
+        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) {
+        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]);
+        }
+    }
+    VIR_FREE(leases);
+    return rv;
+}
+
+static int
+remoteDispatchNetworkGetDHCPLeaseForMAC(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                        virNetServerClientPtr client,
+                                        virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                        virNetMessageErrorPtr rerr,
+                                        remote_network_get_dhcp_lease_for_mac_args *args,
+                                        remote_network_get_dhcp_lease_for_mac_ret *ret)
+{
+    int rv = -1;
+    struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+    virNetworkDHCPLeases lease;
+    virNetworkPtr net = NULL;
+    const char *mac;
+    remote_network_dhcp_lease *lease_ret = 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 ((rv = virNetworkGetDHCPLeaseForMAC(net, mac, &lease,
+                                           args->flags)) < 0)
+        goto cleanup;
+
+    lease_ret = &ret->lease;
+    lease_ret->expirytime = lease.expirytime;
+
+    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))
+        rv = -1;
+
+cleanup:
+    if (rv < 0)
+        virNetMessageSaveError(rerr);
+    return rv;
+}
 
 /*----- Helpers. -----*/
 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 62e77a5..f2cf2fc 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -6599,6 +6599,121 @@ done:
     return rv;
 }
 
+static int
+remoteNetworkGetDHCPLeaseForMAC(virNetworkPtr net,
+                                const char *mac,
+                                virNetworkDHCPLeasesPtr lease,
+                                unsigned int flags)
+{
+    int rv = -1;
+    struct private_data *priv = net->conn->networkPrivateData;
+    remote_network_get_dhcp_lease_for_mac_args args;
+    remote_network_get_dhcp_lease_for_mac_ret 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_LEASE_FOR_MAC,
+             (xdrproc_t)xdr_remote_network_get_dhcp_lease_for_mac_args, (char *)&args,
+             (xdrproc_t)xdr_remote_network_get_dhcp_lease_for_mac_ret, (char *)&ret) == -1) {
+        goto done;
+    }
+
+    lease->expirytime = ret.lease.expirytime;
+
+    if ((VIR_STRDUP(lease->mac, ret.lease.mac) < 0) ||
+        (VIR_STRDUP(lease->ipaddr, ret.lease.ipaddr) < 0) ||
+        (VIR_STRDUP(lease->hostname, ret.lease.hostname) < 0) ||
+        (VIR_STRDUP(lease->clientid, ret.lease.clientid) < 0))
+        goto cleanup;
+
+    rv = 1;
+
+cleanup:
+    xdr_free((xdrproc_t)xdr_remote_network_get_dhcp_lease_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);
+        return -1;
+        goto cleanup;
+    }
+
+    if (ret.leases.leases_len &&
+        VIR_ALLOC_N(leases_ret, ret.leases.leases_len) < 0) {
+        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;
+
+        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 +7073,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 */
+    .networkGetDHCPLeaseForMAC = remoteNetworkGetDHCPLeaseForMAC, /* 1.1.3 */
 };
 
 static virInterfaceDriver interface_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index a1c23da..75d2c60 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 = 1024;
+
 /* UUID.  VIR_UUID_BUFLEN definition comes from libvirt.h */
 typedef opaque remote_uuid[VIR_UUID_BUFLEN];
 
@@ -2835,6 +2840,33 @@ 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;
+};
+
+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>;
+};
+
+struct remote_network_get_dhcp_lease_for_mac_args {
+    remote_nonnull_network net;
+    remote_string mac;
+    unsigned int flags;
+};
+
+struct remote_network_get_dhcp_lease_for_mac_ret {
+    remote_network_dhcp_lease lease;
+};
+
 /*----- Protocol. -----*/
 
 /* Define the program number, protocol version and procedure numbers here. */
@@ -4998,5 +5030,19 @@ enum remote_procedure {
      * @generate: both
      * @acl: none
      */
-    REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311
+    REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311,
+
+    /**
+     * @generate: none
+     * @priority: high
+     * @acl: network:read
+     */
+    REMOTE_PROC_NETWORK_GET_DHCP_LEASES = 312,
+
+    /**
+     * @generate: none
+     * @priority: high
+     * @acl: network:read
+     */
+    REMOTE_PROC_NETWORK_GET_DHCP_LEASE_FOR_MAC = 313
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 4e27aae..d8b7237 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2316,6 +2316,31 @@ struct remote_domain_event_device_removed_msg {
         remote_nonnull_domain      dom;
         remote_nonnull_string      devAlias;
 };
+struct remote_network_dhcp_lease {
+        int64_t                    expirytime;
+        remote_nonnull_string      mac;
+        remote_nonnull_string      ipaddr;
+        remote_nonnull_string      hostname;
+        remote_nonnull_string      clientid;
+};
+struct remote_network_get_dhcp_leases_args {
+        remote_nonnull_network     net;
+        u_int                      flags;
+};
+struct remote_network_get_dhcp_leases_ret {
+        struct {
+                u_int              leases_len;
+                remote_network_dhcp_lease * leases_val;
+        } leases;
+};
+struct remote_network_get_dhcp_lease_for_mac_args {
+        remote_nonnull_network     net;
+        remote_string              mac;
+        u_int                      flags;
+};
+struct remote_network_get_dhcp_lease_for_mac_ret {
+        remote_network_dhcp_lease  lease;
+};
 enum remote_procedure {
         REMOTE_PROC_CONNECT_OPEN = 1,
         REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -2628,4 +2653,6 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_CREATE_XML_WITH_FILES = 309,
         REMOTE_PROC_DOMAIN_CREATE_WITH_FILES = 310,
         REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311,
+        REMOTE_PROC_NETWORK_GET_DHCP_LEASES = 312,
+        REMOTE_PROC_NETWORK_GET_DHCP_LEASE_FOR_MAC = 313,
 };
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index ceb1ad8..5a503cf 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -66,6 +66,7 @@ sub fixup_name {
     $name =~ s/Fstrim$/FSTrim/;
     $name =~ s/Scsi/SCSI/;
     $name =~ s/Wwn$/WWN/;
+    $name =~ s/Dhcp$/DHCP/;
 
     return $name;
 }
-- 
1.7.11.7


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]