net-dhcp-leases: Implement the remote protocol

Implement RPC calls for virNetworkGetDHCPLeases, virNetworkGetDHCPLeasesForMAC

daemon/remote.c
   * Define remoteSerializeNetworkDHCPLeases,
            remoteDispatchNetworkGetDHCPLeases
   * Define remoteDispatchNetworkGetDHCPLeasesForMAC
   * Define helper function remoteSerializeDHCPLease

src/remote/remote_driver.c
   * Define remoteNetworkGetDHCPLeases
   * Define remoteNetworkGetDHCPLeasesForMAC
   * Define helper function remoteSerializeDHCPLease

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
This commit is contained in:
Nehal J Wani 2014-06-24 02:31:50 +05:30 committed by Daniel P. Berrange
parent 03e0e79e07
commit 990c3b6554
5 changed files with 458 additions and 1 deletions

View File

@ -6202,7 +6202,190 @@ remoteDispatchNodeGetFreePages(virNetServerPtr server ATTRIBUTE_UNUSED,
VIR_FREE(ret->counts.counts_val);
}
return rv;
}
/* Copy contents of virNetworkDHCPLeasePtr to remote_network_dhcp_lease */
static int
remoteSerializeDHCPLease(remote_network_dhcp_lease *lease_dst, virNetworkDHCPLeasePtr lease_src)
{
char **mac_tmp = NULL;
char **iaid_tmp = NULL;
char **hostname_tmp = NULL;
char **clientid_tmp = NULL;
if (VIR_ALLOC(mac_tmp) < 0 ||
VIR_ALLOC(iaid_tmp) < 0 ||
VIR_ALLOC(hostname_tmp) < 0 ||
VIR_ALLOC(clientid_tmp) < 0)
goto error;
lease_dst->expirytime = lease_src->expirytime;
lease_dst->type = lease_src->type;
lease_dst->prefix = lease_src->prefix;
if (VIR_STRDUP(lease_dst->interface, lease_src->interface) < 0 ||
VIR_STRDUP(lease_dst->ipaddr, lease_src->ipaddr) < 0 ||
VIR_STRDUP(*mac_tmp, lease_src->mac) < 0 ||
VIR_STRDUP(*iaid_tmp, lease_src->iaid) < 0 ||
VIR_STRDUP(*hostname_tmp, lease_src->hostname) < 0 ||
VIR_STRDUP(*clientid_tmp, lease_src->clientid) < 0)
goto error;
lease_dst->mac = *mac_tmp ? mac_tmp : NULL;
lease_dst->iaid = *iaid_tmp ? iaid_tmp : NULL;
lease_dst->hostname = *hostname_tmp ? hostname_tmp : NULL;
lease_dst->clientid = *clientid_tmp ? clientid_tmp : NULL;
return 0;
error:
VIR_FREE(*mac_tmp);
VIR_FREE(*iaid_tmp);
VIR_FREE(*hostname_tmp);
VIR_FREE(*clientid_tmp);
VIR_FREE(mac_tmp);
VIR_FREE(iaid_tmp);
VIR_FREE(hostname_tmp);
VIR_FREE(clientid_tmp);
VIR_FREE(lease_dst->ipaddr);
VIR_FREE(lease_dst->interface);
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;
size_t i;
struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
virNetworkDHCPLeasePtr *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,
args->need_results ? &leases : NULL,
args->flags)) < 0)
goto cleanup;
if (nleases > REMOTE_NETWORK_DHCP_LEASES_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of leases is %d, which exceeds max limit: %d"),
nleases, REMOTE_NETWORK_DHCP_LEASES_MAX);
goto cleanup;
}
if (leases && nleases) {
if (VIR_ALLOC_N(ret->leases.leases_val, nleases) < 0)
goto cleanup;
ret->leases.leases_len = nleases;
for (i = 0; i < nleases; i++) {
if (remoteSerializeDHCPLease(ret->leases.leases_val + i, leases[i]) < 0)
goto cleanup;
}
} else {
ret->leases.leases_len = 0;
ret->leases.leases_val = NULL;
}
ret->ret = nleases;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
if (leases) {
for (i = 0; i < nleases; i++)
virNetworkDHCPLeaseFree(leases[i]);
VIR_FREE(leases);
}
virNetworkFree(net);
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;
size_t i;
struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
virNetworkDHCPLeasePtr *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 = virNetworkGetDHCPLeasesForMAC(net, args->mac,
args->need_results ? &leases : NULL,
args->flags)) < 0)
goto cleanup;
if (nleases > REMOTE_NETWORK_DHCP_LEASES_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of leases is %d, which exceeds max limit: %d"),
nleases, REMOTE_NETWORK_DHCP_LEASES_MAX);
return -1;
}
if (leases && nleases) {
if (VIR_ALLOC_N(ret->leases.leases_val, nleases) < 0)
goto cleanup;
ret->leases.leases_len = nleases;
for (i = 0; i < nleases; i++) {
if (remoteSerializeDHCPLease(ret->leases.leases_val + i, leases[i]) < 0)
goto cleanup;
}
} else {
ret->leases.leases_len = 0;
ret->leases.leases_val = NULL;
}
ret->ret = nleases;
rv = 0;
cleanup:
if (rv < 0)
virNetMessageSaveError(rerr);
if (leases) {
for (i = 0; i < nleases; i++)
virNetworkDHCPLeaseFree(leases[i]);
VIR_FREE(leases);
}
virNetworkFree(net);
return rv;
}

View File

@ -7549,6 +7549,190 @@ remoteNodeGetFreePages(virConnectPtr conn,
}
/* Copy contents of remote_network_dhcp_lease to virNetworkDHCPLeasePtr */
static int
remoteSerializeDHCPLease(virNetworkDHCPLeasePtr lease_dst, remote_network_dhcp_lease *lease_src)
{
lease_dst->expirytime = lease_src->expirytime;
lease_dst->type = lease_src->type;
lease_dst->prefix = lease_src->prefix;
if (VIR_STRDUP(lease_dst->interface, lease_src->interface) < 0)
goto error;
if (VIR_STRDUP(lease_dst->ipaddr, lease_src->ipaddr) < 0)
goto error;
if (lease_src->mac) {
if (VIR_STRDUP(lease_dst->mac, *lease_src->mac) < 0)
goto error;
} else {
lease_src->mac = NULL;
}
if (lease_src->iaid) {
if (VIR_STRDUP(lease_dst->iaid, *lease_src->iaid) < 0)
goto error;
} else {
lease_src->iaid = NULL;
}
if (lease_src->hostname) {
if (VIR_STRDUP(lease_dst->hostname, *lease_src->hostname) < 0)
goto error;
} else {
lease_src->hostname = NULL;
}
if (lease_src->clientid) {
if (VIR_STRDUP(lease_dst->clientid, *lease_src->clientid) < 0)
goto error;
} else {
lease_src->clientid = NULL;
}
return 0;
error:
virNetworkDHCPLeaseFree(lease_dst);
return -1;
}
static int
remoteNetworkGetDHCPLeases(virNetworkPtr net,
virNetworkDHCPLeasePtr **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;
virNetworkDHCPLeasePtr *leases_ret = NULL;
remoteDriverLock(priv);
make_nonnull_network(&args.net, net);
args.flags = flags;
args.need_results = !!leases;
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_DHCP_LEASES_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of leases is %d, which exceeds max limit: %d"),
ret.leases.leases_len, REMOTE_NETWORK_DHCP_LEASES_MAX);
goto cleanup;
}
if (leases) {
if (ret.leases.leases_len &&
VIR_ALLOC_N(leases_ret, ret.leases.leases_len + 1) < 0)
goto cleanup;
for (i = 0; i < ret.leases.leases_len; i++) {
if (VIR_ALLOC(leases_ret[i]) < 0)
goto cleanup;
if (remoteSerializeDHCPLease(leases_ret[i], &ret.leases.leases_val[i]) < 0)
goto cleanup;
}
*leases = leases_ret;
leases_ret = NULL;
}
rv = ret.ret;
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 int
remoteNetworkGetDHCPLeasesForMAC(virNetworkPtr net,
const char *mac,
virNetworkDHCPLeasePtr **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;
virNetworkDHCPLeasePtr *leases_ret = NULL;
remoteDriverLock(priv);
make_nonnull_network(&args.net, net);
args.mac = (char *) mac;
args.flags = flags;
args.need_results = !!leases;
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_DHCP_LEASES_MAX) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Number of leases is %d, which exceeds max limit: %d"),
ret.leases.leases_len, REMOTE_NETWORK_DHCP_LEASES_MAX);
goto cleanup;
}
if (leases) {
if (ret.leases.leases_len &&
VIR_ALLOC_N(leases_ret, ret.leases.leases_len + 1) < 0)
goto cleanup;
for (i = 0; i < ret.leases.leases_len; i++) {
if (VIR_ALLOC(leases_ret[i]) < 0)
goto cleanup;
if (remoteSerializeDHCPLease(leases_ret[i], &ret.leases.leases_val[i]) < 0)
goto cleanup;
}
*leases = leases_ret;
leases_ret = NULL;
}
rv = ret.ret;
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;
}
/* get_nonnull_domain and get_nonnull_network turn an on-wire
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
* These can return NULL if underlying memory allocations fail,
@ -7913,6 +8097,8 @@ static virNetworkDriver network_driver = {
.networkSetAutostart = remoteNetworkSetAutostart, /* 0.3.0 */
.networkIsActive = remoteNetworkIsActive, /* 0.7.3 */
.networkIsPersistent = remoteNetworkIsPersistent, /* 0.7.3 */
.networkGetDHCPLeases = remoteNetworkGetDHCPLeases, /* 1.2.6 */
.networkGetDHCPLeasesForMAC = remoteNetworkGetDHCPLeasesForMAC, /* 1.2.6 */
};
static virInterfaceDriver interface_driver = {

View File

@ -238,6 +238,9 @@ const REMOTE_CONNECT_CPU_MODELS_MAX = 8192;
/* Upper limit on number of mountpoints to frozen */
const REMOTE_DOMAIN_FSFREEZE_MOUNTPOINTS_MAX = 256;
/* Upper limit on the maximum number of leases in one lease file */
const REMOTE_NETWORK_DHCP_LEASES_MAX = 65536;
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@ -3018,6 +3021,40 @@ struct remote_node_get_free_pages_ret {
unsigned hyper counts<REMOTE_NODE_MAX_CELLS>;
};
struct remote_network_dhcp_lease {
remote_nonnull_string interface;
hyper expirytime;
int type;
remote_string mac;
remote_string iaid;
remote_nonnull_string ipaddr;
unsigned int prefix;
remote_string hostname;
remote_string clientid;
};
struct remote_network_get_dhcp_leases_args {
remote_nonnull_network net;
int need_results;
unsigned int flags;
};
struct remote_network_get_dhcp_leases_ret {
remote_network_dhcp_lease leases<REMOTE_NETWORK_DHCP_LEASES_MAX>;
unsigned int ret;
};
struct remote_network_get_dhcp_leases_for_mac_args {
remote_nonnull_network net;
remote_nonnull_string mac;
int need_results;
unsigned int flags;
};
struct remote_network_get_dhcp_leases_for_mac_ret {
remote_network_dhcp_lease leases<REMOTE_NETWORK_DHCP_LEASES_MAX>;
unsigned int ret;
};
/*----- Protocol. -----*/
@ -5370,5 +5407,17 @@ enum remote_procedure {
* @priority: high
* @acl: connect:read
*/
REMOTE_PROC_NODE_GET_FREE_PAGES = 340
REMOTE_PROC_NODE_GET_FREE_PAGES = 340,
/**
* @generate: none
* @acl: network:read
*/
REMOTE_PROC_NETWORK_GET_DHCP_LEASES = 341,
/**
* @generate: none
* @acl: network:read
*/
REMOTE_PROC_NETWORK_GET_DHCP_LEASES_FOR_MAC = 342
};

View File

@ -2485,6 +2485,42 @@ struct remote_node_get_free_pages_ret {
uint64_t * counts_val;
} counts;
};
struct remote_network_dhcp_lease {
remote_nonnull_string interface;
int64_t expirytime;
int type;
remote_string mac;
remote_string iaid;
remote_nonnull_string ipaddr;
u_int prefix;
remote_string hostname;
remote_string clientid;
};
struct remote_network_get_dhcp_leases_args {
remote_nonnull_network net;
int need_results;
u_int flags;
};
struct remote_network_get_dhcp_leases_ret {
struct {
u_int leases_len;
remote_network_dhcp_lease * leases_val;
} leases;
u_int ret;
};
struct remote_network_get_dhcp_leases_for_mac_args {
remote_nonnull_network net;
remote_nonnull_string mac;
int need_results;
u_int flags;
};
struct remote_network_get_dhcp_leases_for_mac_ret {
struct {
u_int leases_len;
remote_network_dhcp_lease * leases_val;
} leases;
u_int ret;
};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@ -2826,4 +2862,6 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SET_TIME = 338,
REMOTE_PROC_DOMAIN_EVENT_BLOCK_JOB_2 = 339,
REMOTE_PROC_NODE_GET_FREE_PAGES = 340,
REMOTE_PROC_NETWORK_GET_DHCP_LEASES = 341,
REMOTE_PROC_NETWORK_GET_DHCP_LEASES_FOR_MAC = 342,
};

View File

@ -68,6 +68,7 @@ sub fixup_name {
$name =~ s/Fsthaw$/FSThaw/;
$name =~ s/Scsi/SCSI/;
$name =~ s/Wwn$/WWN/;
$name =~ s/Dhcp$/DHCP/;
return $name;
}