[libvirt] [PATCH 1/7] Introduce virDomainInterfacesAddresses API

Michal Privoznik mprivozn at redhat.com
Fri Jun 8 08:04:32 UTC 2012


This API returns dynamically allocated array of IP addresses for
all domain interfaces.
---
 include/libvirt/libvirt.h.in |   32 +++++++++++++
 python/generator.py          |    1 +
 src/driver.h                 |    6 +++
 src/libvirt.c                |  101 ++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |    5 ++
 5 files changed, 145 insertions(+), 0 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index da3ce29..604e598 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1659,6 +1659,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 */
+    int prefix;     /* IP address prefix */
+};
+
+typedef struct _virDomainInterface virDomainInterface;
+typedef virDomainInterface *virDomainInterfacePtr;
+struct _virDomainInterface {
+    char *name;                     /* interface name */
+    char *hwaddr;                   /* hardware address */
+    unsigned int ip_addrs_count;    /* number of items in @ip_addr */
+    virDomainIPAddressPtr ip_addrs; /* array of IP addresses */
+};
+
+int             virDomainInterfacesAddresses (virDomainPtr dom,
+                                              virDomainInterfacePtr *ifaces,
+                                              unsigned int *ifaces_count,
+                                              unsigned int flags);
+
 /* Management of domain block devices */
 
 int                     virDomainBlockPeek (virDomainPtr dom,
diff --git a/python/generator.py b/python/generator.py
index 9530867..747d1a8 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -425,6 +425,7 @@ skip_impl = (
     'virDomainGetInterfaceParameters',
     'virDomainGetCPUStats',
     'virDomainGetDiskErrors',
+    'virDomainInterfacesAddresses',
 )
 
 qemu_skip_impl = (
diff --git a/src/driver.h b/src/driver.h
index aa7a377..336ad31 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -394,6 +394,11 @@ typedef int
                                           const char *device,
                                           virTypedParameterPtr params,
                                           int *nparams, unsigned int flags);
+typedef int
+    (*virDrvDomainInterfacesAddresses)   (virDomainPtr dom,
+                                          virDomainInterfacePtr *ifaces,
+                                          unsigned int *ifaces_count,
+                                          unsigned int flags);
 
 typedef int
     (*virDrvDomainMemoryStats)
@@ -943,6 +948,7 @@ struct _virDriver {
     virDrvDomainInterfaceStats  domainInterfaceStats;
     virDrvDomainSetInterfaceParameters domainSetInterfaceParameters;
     virDrvDomainGetInterfaceParameters domainGetInterfaceParameters;
+    virDrvDomainInterfacesAddresses    domainInterfacesAddresses;
     virDrvDomainMemoryStats     domainMemoryStats;
     virDrvDomainBlockPeek	domainBlockPeek;
     virDrvDomainMemoryPeek      domainMemoryPeek;
diff --git a/src/libvirt.c b/src/libvirt.c
index 6386ed4..2e30a14 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -7347,6 +7347,107 @@ error:
 }
 
 /**
+ * virDomainInterfacesAddresses:
+ * @dom: domain object
+ * @ifaces: array of @dom interfaces
+ * @ifaces_count: number of items in @ifaces
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Return an array of interfaces presented in given domain
+ * among with their IP and HW addresses. Note, that single
+ * interface can have multiple or even none IP address.
+ *
+ * This API dynamically allocates the virDomainInterfacePtr
+ * struct based on how much interfaces domain @dom has,
+ * usually there's 1:1 correlation. The count of elements
+ * allocated is stored in @ifaces_count.
+ *
+ * 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 HW 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;
+ * unsigned int ifaces_count = 0;
+ * unsigned int i, j;
+ * virDomainPtr dom = ... obtain a domain here ...;
+ *
+ * if (virDomainInterfacesAddresses(dom, &ifaces, &ifaces_count, 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].ip_addrs_count; j++) {
+ *         virDomainIPAddressPtr ip_addr = ifaces[i].ip_addrs + j;
+ *         printf("[addr: %s prefix: %d type: %d]",
+ *                ip_addr->addr, ip_addr->prefix, ip_addr->type);
+ *     }
+ *     printf("\n");
+ * }
+ *
+ * cleanup:
+ * for (i = 0; i < ifaces_count; i++) {
+ *     free(ifaces[i].name);
+ *     free(ifaces[i].hwaddr);
+ *     for (j = 0; j < ifaces[i].ip_addrs_count; j++)
+ *         free(ifaces[i].ip_addrs[j].addr);
+ *     free(ifaces[i].ip_addrs);
+ * }
+ * free(ifaces);
+ *
+ * Returns 0 on success,
+ *         -1 in case of error
+ */
+int
+virDomainInterfacesAddresses (virDomainPtr dom,
+                              virDomainInterfacePtr *ifaces,
+                              unsigned int *ifaces_count,
+                              unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(dom, "ifaces=%p, ifaces_count=%p, flags=%x",
+                     ifaces, ifaces_count, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECTED_DOMAIN(dom)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        goto error;
+    }
+
+    conn = dom->conn;
+
+    virCheckNonNullArgGoto(ifaces, error);
+    virCheckNonNullArgGoto(ifaces_count, error);
+
+    if (conn->driver->domainInterfacesAddresses) {
+        int ret;
+        ret = conn->driver->domainInterfacesAddresses(dom, ifaces,
+                                                      ifaces_count, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(dom ? dom->conn : NULL);
+    return -1;
+}
+
+/**
  * virDomainMemoryStats:
  * @dom: pointer to the domain object
  * @stats: nr_stats-sized array of stat structures (returned)
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 46c13fb..54b094e 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -534,4 +534,9 @@ LIBVIRT_0.9.11 {
         virDomainPMWakeup;
 } LIBVIRT_0.9.10;
 
+LIBVIRT_0.9.13 {
+    global:
+        virDomainInterfacesAddresses;
+} LIBVIRT_0.9.11;
+
 # .... define new API here using predicted next version number ....
-- 
1.7.8.5




More information about the libvir-list mailing list