Implement RPC calls for virDomainInterfacesAddresses daemon/remote.c * Define remoteSerializeDomainInterfacePtr, remoteDispatchDomainInterfacesAddresses src/remote/remote_driver.c * Define remoteDomainInterfacesAddresses src/remote/remote_protocol.x * New RPC procedure: REMOTE_PROC_DOMAIN_INTERFACES_ADDRESSES * Define structs remote_domain_ip_addr, remote_domain_interface, remote_domain_interfaces_addresses_args, remote_domain_interfaces_addresses_ret src/remote_protocol-structs * New structs added --- daemon/remote.c | 123 +++++++++++++++++++++++++++++++++++++++++++ src/remote/remote_driver.c | 93 ++++++++++++++++++++++++++++++++ src/remote/remote_protocol.x | 32 ++++++++++- src/remote_protocol-structs | 24 +++++++++ 4 files changed, 270 insertions(+), 2 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index 03d5557..4c3bb4f 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -5025,6 +5025,129 @@ cleanup: return rv; } +static int +remoteSerializeDomainInterfacePtr(virDomainInterfacePtr ifaces, + unsigned int ifaces_count, + remote_domain_interfaces_addresses_ret *ret) +{ + size_t i, j; + + if (VIR_ALLOC_N(ret->ifaces.ifaces_val, ifaces_count) < 0) + return -1; + + ret->ifaces.ifaces_len = ifaces_count; + + for (i = 0; i < ifaces_count; i++) { + virDomainInterfacePtr iface = &(ifaces[i]); + remote_domain_interface *iface_ret = &(ret->ifaces.ifaces_val[i]); + + if ((VIR_STRDUP(iface_ret->name, iface->name)) < 0) + goto no_memory; + + if (iface->hwaddr) { + char **hwaddr_p = NULL; + if (VIR_ALLOC(hwaddr_p) < 0) + goto no_memory; + if (VIR_STRDUP(*hwaddr_p, iface->hwaddr) < 0) + goto no_memory; + + iface_ret->hwaddr = hwaddr_p; + } + + if (VIR_ALLOC_N(iface_ret->ip_addrs.ip_addrs_val, + iface->ip_addrs_count) < 0) + goto no_memory; + + iface_ret->ip_addrs.ip_addrs_len = iface->ip_addrs_count; + + for (j = 0; j < iface->ip_addrs_count; j++) { + virDomainIPAddressPtr ip_addr = &(iface->ip_addrs[j]); + remote_domain_ip_addr *ip_addr_ret = + &(iface_ret->ip_addrs.ip_addrs_val[j]); + + if (VIR_STRDUP(ip_addr_ret->addr, ip_addr->addr) < 0) + goto no_memory; + + ip_addr_ret->prefix = ip_addr->prefix; + ip_addr_ret->type = ip_addr->type; + } + } + + return 0; + +no_memory: + if (ret->ifaces.ifaces_val) { + for (i = 0; i < ifaces_count; i++) { + remote_domain_interface *iface_ret = &(ret->ifaces.ifaces_val[i]); + VIR_FREE(iface_ret->name); + VIR_FREE(iface_ret->hwaddr); + for (j = 0; j < iface_ret->ip_addrs.ip_addrs_len; j++) { + remote_domain_ip_addr *ip_addr = + &(iface_ret->ip_addrs.ip_addrs_val[j]); + VIR_FREE(ip_addr->addr); + } + VIR_FREE(iface_ret); + } + VIR_FREE(ret->ifaces.ifaces_val); + } + + return -1; +} + +static int +remoteDispatchDomainInterfacesAddresses( + virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_interfaces_addresses_args *args, + remote_domain_interfaces_addresses_ret *ret) +{ + int rv = -1; + virDomainPtr dom = NULL; + virDomainInterfacePtr ifaces = NULL; + unsigned int ifaces_count = 0; + struct daemonClientPrivate *priv = + virNetServerClientGetPrivateData(client); + + if (!priv->conn) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open")); + goto cleanup; + } + + if (!(dom = get_nonnull_domain(priv->conn, args->dom))) + goto cleanup; + + if (virDomainInterfacesAddresses(dom, &ifaces, + &ifaces_count, args->flags) < 0) + goto cleanup; + + if (remoteSerializeDomainInterfacePtr(ifaces, ifaces_count, ret) < 0) + goto cleanup; + + rv = 0; + +cleanup: + if (rv < 0) + virNetMessageSaveError(rerr); + if (dom) + virDomainFree(dom); + if (ifaces) { + size_t i, j; + + for (i = 0; i < ifaces_count; i++) { + VIR_FREE(ifaces[i].name); + VIR_FREE(ifaces[i].hwaddr); + for (j = 0; j < ifaces[i].ip_addrs_count; j++) + VIR_FREE(ifaces[i].ip_addrs[j].addr); + VIR_FREE(ifaces[i].ip_addrs); + } + VIR_FREE(ifaces); + } + return rv; +} + + /*----- Helpers. -----*/ diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index f828eef..18f18c7 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -6476,6 +6476,98 @@ done: return rv; } +static int +remoteDomainInterfacesAddresses(virDomainPtr dom, + virDomainInterfacePtr *ifaces, + unsigned int *ifaces_count, + unsigned int flags) +{ + int rv = -1; + remote_domain_interfaces_addresses_args args; + remote_domain_interfaces_addresses_ret ret; + struct private_data *priv = dom->conn->privateData; + size_t i, j; + + memset(&ret, 0, sizeof(ret)); + args.flags = flags; + make_nonnull_domain(&args.dom, dom); + + remoteDriverLock(priv); + + if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_INTERFACES_ADDRESSES, + (xdrproc_t)xdr_remote_domain_interfaces_addresses_args, + (char *)&args, + (xdrproc_t)xdr_remote_domain_interfaces_addresses_ret, + (char *)&ret) == -1) { + goto done; + } + + if (ret.ifaces.ifaces_len && + VIR_ALLOC_N(*ifaces, ret.ifaces.ifaces_len) < 0) { + virReportOOMError(); + goto cleanup; + } + + *ifaces_count = ret.ifaces.ifaces_len; + + for (i = 0; i < *ifaces_count; i++) { + virDomainInterfacePtr iface = &((*ifaces)[i]); + remote_domain_interface *iface_ret = &(ret.ifaces.ifaces_val[i]); + + if (VIR_STRDUP(iface->name, iface_ret->name) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (iface_ret->hwaddr && + VIR_STRDUP(iface->hwaddr, *iface_ret->hwaddr) < 0) { + virReportOOMError(); + goto cleanup; + } + + iface->ip_addrs_count = iface_ret->ip_addrs.ip_addrs_len; + + if (iface->ip_addrs_count) { + if (VIR_ALLOC_N(iface->ip_addrs, iface->ip_addrs_count) < 0) { + virReportOOMError(); + goto cleanup; + } + + for (j = 0; j < iface->ip_addrs_count; j++) { + virDomainIPAddressPtr ip_addr = &(iface->ip_addrs[j]); + remote_domain_ip_addr *ip_addr_ret = + &(iface_ret->ip_addrs.ip_addrs_val[j]); + + if (VIR_STRDUP(ip_addr->addr, ip_addr_ret->addr) < 0) { + virReportOOMError(); + goto cleanup; + } + ip_addr->prefix = ip_addr_ret->prefix; + ip_addr->type = ip_addr_ret->type; + } + } + } + + rv = 0; + +cleanup: + if (rv < 0) { + for (i = 0; i < *ifaces_count; i++) { + VIR_FREE((*ifaces)[i].name); + VIR_FREE((*ifaces)[i].hwaddr); + for (j = 0; j < (*ifaces)[i].ip_addrs_count; j++) + VIR_FREE((*ifaces)[i].ip_addrs[j].addr); + VIR_FREE((*ifaces)[i].ip_addrs); + } + VIR_FREE(*ifaces); + } + xdr_free((xdrproc_t)xdr_remote_domain_interfaces_addresses_ret, + (char *) &ret); +done: + remoteDriverUnlock(priv); + return rv; +} + static void remoteDomainEventQueue(struct private_data *priv, virDomainEventPtr event) { @@ -6810,6 +6902,7 @@ static virDriver remote_driver = { .domainMigratePerform3Params = remoteDomainMigratePerform3Params, /* 1.1.0 */ .domainMigrateFinish3Params = remoteDomainMigrateFinish3Params, /* 1.1.0 */ .domainMigrateConfirm3Params = remoteDomainMigrateConfirm3Params, /* 1.1.0 */ + .domainInterfacesAddresses = remoteDomainInterfacesAddresses, /* 1.1.2 */ }; static virNetworkDriver network_driver = { diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x index 7cfebdf..27f3634 100644 --- a/src/remote/remote_protocol.x +++ b/src/remote/remote_protocol.x @@ -1,5 +1,5 @@ /* -*- c -*- - * remote_protocol.x: private protocol for communicating between + * remote_protocoa.x: private protocol for communicating between * remote_internal driver and libvirtd. This protocol is * internal and may change at any time. * @@ -2837,6 +2837,27 @@ struct remote_domain_event_device_removed_msg { remote_nonnull_string devAlias; }; +struct remote_domain_ip_addr { + int type; + remote_nonnull_string addr; + int prefix; +}; + +struct remote_domain_interface { + remote_nonnull_string name; + remote_string hwaddr; + remote_domain_ip_addr ip_addrs<>; +}; + +struct remote_domain_interfaces_addresses_args { + remote_nonnull_domain dom; + unsigned int flags; +}; + +struct remote_domain_interfaces_addresses_ret { + remote_domain_interface ifaces<>; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -5000,5 +5021,12 @@ enum remote_procedure { * @generate: both * @acl: none */ - REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311 + REMOTE_PROC_DOMAIN_EVENT_DEVICE_REMOVED = 311, + + /** + * @generate: none + * @acl: domain:read + */ + REMOTE_PROC_DOMAIN_INTERFACES_ADDRESSES = 312 + }; diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs index 4e27aae..3919530 100644 --- a/src/remote_protocol-structs +++ b/src/remote_protocol-structs @@ -2316,6 +2316,29 @@ struct remote_domain_event_device_removed_msg { remote_nonnull_domain dom; remote_nonnull_string devAlias; }; +struct remote_domain_ip_addr { + int type; + remote_nonnull_string addr; + int prefix; +}; +struct remote_domain_interface { + remote_nonnull_string name; + remote_string hwaddr; + struct { + u_int ip_addrs_len; + remote_domain_ip_addr * ip_addrs_val; + } ip_addrs; +}; +struct remote_domain_interfaces_addresses_args { + remote_nonnull_domain dom; + u_int flags; +}; +struct remote_domain_interfaces_addresses_ret { + struct { + u_int ifaces_len; + remote_domain_interface * ifaces_val; + } ifaces; +}; enum remote_procedure { REMOTE_PROC_CONNECT_OPEN = 1, REMOTE_PROC_CONNECT_CLOSE = 2, @@ -2628,4 +2651,5 @@ 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_DOMAIN_INTERFACES_ADDRESSES = 312, }; -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list