On Sun, Sep 1, 2013 at 7:13 PM, Nehal J Wani <nehaljw.kkd1@xxxxxxxxx> wrote: > Define a new API virDomainInterfaceAddresses, which returns > the address information of a running domain's interfaces(s). > If no interface name is specified, it returns the information > of all interfaces, otherwise it only returns the information > of the specificed interface. The address information includes > the MAC and IP addresses. > > Define helper function virDomainInterfaceFree, which allows > the upper layer application to free the domain interface object > conveniently. > > The API is going to provide multiple methods by flags, e.g. > > * Query guest agent > * Parse lease file of dnsmasq > * DHCP snooping > > But at this stage, it will only work with guest agent, and flags > won't be supported. > > include/libvirt/libvirt.h.in: > * Define virDomainInterfaceAddresses, virDomainInterfaceFree > * Define structs virDomainInterface, virDomainIPAddress > > python/generator.py: > * Skip the auto-generation for virDomainInterfaceAddresses > and virDomainInterfaceFree > > src/driver.h: > * Define domainInterfaceAddresses > > src/libvirt.c: > * Implement virDomainInterfaceAddresses > * Implement virDomainInterfaceFree > > src/libvirt_public.syms: > * Export the new symbols > > --- > include/libvirt/libvirt.h.in | 32 ++++++++++++ > python/generator.py | 3 ++ > src/driver.h | 6 +++ > src/libvirt.c | 115 +++++++++++++++++++++++++++++++++++++++++++ > src/libvirt_public.syms | 6 +++ > 5 files changed, 162 insertions(+) > > diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in > index a47e33c..1a34d02 100644 > --- a/include/libvirt/libvirt.h.in > +++ b/include/libvirt/libvirt.h.in > @@ -2044,6 +2044,38 @@ int virDomainGetInterfaceParameters (virDomainPtr dom, > virTypedParameterPtr params, > int *nparams, unsigned int flags); > > +typedef enum { > + VIR_IP_ADDR_TYPE_IPV4, > + VIR_IP_ADDR_TYPE_IPV6, > + > +#ifdef VIR_ENUM_SENTINELS > + VIR_IP_ADDR_TYPE_LAST > +#endif > +} virIPAddrType; > + > +typedef struct _virDomainInterfaceIPAddress virDomainIPAddress; > +typedef virDomainIPAddress *virDomainIPAddressPtr; > +struct _virDomainInterfaceIPAddress { > + int type; /* virIPAddrType */ > + char *addr; /* IP address */ > + unsigned int prefix; /* IP address prefix */ > +}; > + > +typedef struct _virDomainInterface virDomainInterface; > +typedef virDomainInterface *virDomainInterfacePtr; > +struct _virDomainInterface { > + char *name; /* interface name */ > + char *hwaddr; /* hardware address */ > + unsigned int naddrs; /* number of items in @addrs */ > + virDomainIPAddressPtr addrs; /* array of IP addresses */ > +}; > + > +int virDomainInterfaceAddresses(virDomainPtr dom, > + virDomainInterfacePtr **ifaces, > + unsigned int flags); > + > +void virDomainInterfaceFree(virDomainInterfacePtr iface); > + > /* Management of domain block devices */ > > int virDomainBlockPeek (virDomainPtr dom, > diff --git a/python/generator.py b/python/generator.py > index fb321c6..50f779b 100755 > --- a/python/generator.py > +++ b/python/generator.py > @@ -458,6 +458,7 @@ skip_impl = ( > 'virNodeGetMemoryParameters', > 'virNodeSetMemoryParameters', > 'virNodeGetCPUMap', > + 'virDomainInterfaceAddresses', > 'virDomainMigrate3', > 'virDomainMigrateToURI3', > ) > @@ -560,6 +561,8 @@ skip_function = ( > "virTypedParamsGetString", > "virTypedParamsGetUInt", > "virTypedParamsGetULLong", > + > + "virDomainInterfaceFree", # Only useful in C > ) > > lxc_skip_function = ( > diff --git a/src/driver.h b/src/driver.h > index be64333..eb4927b 100644 > --- a/src/driver.h > +++ b/src/driver.h > @@ -518,6 +518,11 @@ typedef int > unsigned int flags); > > typedef int > +(*virDrvDomainInterfaceAddresses)(virDomainPtr dom, > + virDomainInterfacePtr **ifaces, > + unsigned int flags); > + > +typedef int > (*virDrvDomainMemoryStats)(virDomainPtr domain, > struct _virDomainMemoryStat *stats, > unsigned int nr_stats, > @@ -1238,6 +1243,7 @@ struct _virDriver { > virDrvDomainInterfaceStats domainInterfaceStats; > virDrvDomainSetInterfaceParameters domainSetInterfaceParameters; > virDrvDomainGetInterfaceParameters domainGetInterfaceParameters; > + virDrvDomainInterfaceAddresses domainInterfaceAddresses; > virDrvDomainMemoryStats domainMemoryStats; > virDrvDomainBlockPeek domainBlockPeek; > virDrvDomainMemoryPeek domainMemoryPeek; > diff --git a/src/libvirt.c b/src/libvirt.c > index 07a3fd5..82c117f 100644 > --- a/src/libvirt.c > +++ b/src/libvirt.c > @@ -8643,6 +8643,96 @@ error: > return -1; > } > > + /** > + * virDomainInterfaceAddresses: > + * @dom: domain object > + * @ifaces: pointer to an array of pointers pointing to interface objects > + * @flags: extra flags; not used yet, so callers should always pass 0 > + * > + * Return a pointer to the allocated array of pointers pointing to interfaces > + * present in given domain along with their IP and MAC addresses. Note that > + * single interface can have multiple or even 0 IP address. > + * > + * This API dynamically allocates the virDomainInterfacePtr struct based > + * on how many interfaces domain @dom has, usually there's 1:1 correlation. > + * The count of the interfaces is returned as the return value. > + * > + * Note that for some hypervisors, a configured guest agent is needed for > + * successful return from this API. Moreover, if guest agent is used then > + * the interface name is the one seen by guest OS. To match such interface > + * with the one from @dom XML use MAC address or IP range. > + * > + * @ifaces->name is never NULL, @ifaces->hwaddr might be NULL. > + * > + * The caller *must* free @ifaces when no longer needed. Usual use case > + * looks like this: > + * > + * virDomainInterfacePtr *ifaces = NULL; > + * int ifaces_count = 0; > + * size_t i, j; > + * virDomainPtr dom = ... obtain a domain here ...; > + * > + * if ((ifaces_count = virDomainInterfaceAddresses(dom, &ifaces, 0)) < 0) > + * goto cleanup; > + * > + * ... do something with returned values, for example: > + * for (i = 0; i < ifaces_count; i++) { > + * printf("name: %s", ifaces[i]->name); > + * if (ifaces[i]->hwaddr) > + * printf(" hwaddr: %s", ifaces[i]->hwaddr); > + * > + * for (j = 0; j < ifaces[i]->naddrs; j++) { > + * virDomainIPAddressPtr ip_addr = ifaces[i]->addrs + j; > + * printf("[addr: %s prefix: %d type: %d]", > + * ip_addr->addr, ip_addr->prefix, ip_addr->type); > + * } > + * printf("\n"); > + * } > + * > + * cleanup: > + * if (ifaces) > + * for (i = 0; i < ifaces_count; i++) > + * virDomainInterfaceFree(ifaces[i]); > + * VIR_FREE(ifaces); > + * > + * Returns the number of interfaces on success, -1 in case of error. > + */ > +int > +virDomainInterfaceAddresses(virDomainPtr dom, > + virDomainInterfacePtr **ifaces, > + unsigned int flags) > +{ > + virConnectPtr conn; > + > + VIR_DOMAIN_DEBUG(dom, "ifaces=%p, flags=%x", ifaces, flags); > + > + virResetLastError(); > + > + if (!VIR_IS_CONNECTED_DOMAIN(dom)) { > + virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__); > + virDispatchError(NULL); > + return -1; > + } > + > + conn = dom->conn; > + > + virCheckNonNullArgGoto(ifaces, error); > + > + if (conn->driver->domainInterfaceAddresses) { > + int ret; > + ret = conn->driver->domainInterfaceAddresses(dom, ifaces, flags); > + if (ret < 0) > + goto error; > + return ret; > + } > + > + virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); > + > +error: > + virDispatchError(dom->conn); > + return -1; > +} > + > /** > * virDomainMemoryStats: > * @dom: pointer to the domain object > @@ -21961,3 +22051,28 @@ error: > virDispatchError(dom->conn); > return -1; > } > + > +/** > + * virDomainInterfaceFree: > + * @iface: an interface object > + * > + * Free the interface object. The data structure is > + * freed and should not be used thereafter. > + */ > +void > +virDomainInterfaceFree(virDomainInterfacePtr iface) > +{ > + size_t i; > + > + if (!iface) > + return; > + > + VIR_FREE(iface->name); > + VIR_FREE(iface->hwaddr); > + > + for (i = 0; i < iface->naddrs; i++) > + VIR_FREE(iface->addrs[i].addr); > + VIR_FREE(iface->addrs); > + > + VIR_FREE(iface); > +} > diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms > index bbdf78a..35f3a3e 100644 > --- a/src/libvirt_public.syms > +++ b/src/libvirt_public.syms > @@ -634,4 +634,10 @@ LIBVIRT_1.1.1 { > virDomainSetMemoryStatsPeriod; > } LIBVIRT_1.1.0; > > +LIBVIRT_1.1.3 { > + global: > + virDomainInterfaceAddresses; > + virDomainInterfaceFree; > +} LIBVIRT_1.1.1; > + > # .... define new API here using predicted next version number .... > -- > 1.7.11.7 > In agreement with Guido's suggestion on 5/5 of the previous version (https://www.redhat.com/archives/libvir-list/2013-August/msg01271.html), the enums are also to exposed to python bindings, for which, /include/libvirt/libvirt.h.in will have to be modified a bit. Diff has been attached. -- Nehal J Wani
Attachment:
1.diff
Description: Binary data
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list