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

Michal Privoznik mprivozn at redhat.com
Thu Aug 2 18:08:43 UTC 2012


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

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index d21d029..d5d131a 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1713,6 +1713,41 @@ 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 */
+};
+
+typedef enum {
+    VIR_DOMAIN_INTERFACE_ADDRS_DEFAULT      = 0, /* hypervisor choice */
+} virDomainInterfacesAddressesFlags;
+
+int             virDomainInterfacesAddresses (virDomainPtr dom,
+                                              virDomainInterfacePtr *ifaces,
+                                              unsigned int flags);
+
 /* Management of domain block devices */
 
 int                     virDomainBlockPeek (virDomainPtr dom,
diff --git a/python/generator.py b/python/generator.py
index 6559ece..7c1a51d 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -427,6 +427,7 @@ skip_impl = (
     'virDomainGetDiskErrors',
     'virConnectUnregisterCloseCallback',
     'virConnectRegisterCloseCallback',
+    'virDomainInterfacesAddresses',
 )
 
 qemu_skip_impl = (
diff --git a/src/driver.h b/src/driver.h
index aab9766..4460dc9 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -404,6 +404,10 @@ typedef int
                                           const char *device,
                                           virTypedParameterPtr params,
                                           int *nparams, unsigned int flags);
+typedef int
+    (*virDrvDomainInterfacesAddresses)   (virDomainPtr dom,
+                                          virDomainInterfacePtr *ifaces,
+                                          unsigned int flags);
 
 typedef int
     (*virDrvDomainMemoryStats)
@@ -1012,6 +1016,7 @@ struct _virDriver {
     virDrvDomainSnapshotListNames       domainSnapshotListNames;
     virDrvDomainListAllSnapshots        domainListAllSnapshots;
     virDrvDomainSnapshotNumChildren     domainSnapshotNumChildren;
+    virDrvDomainInterfacesAddresses     domainInterfacesAddresses;
     virDrvDomainSnapshotListChildrenNames domainSnapshotListChildrenNames;
     virDrvDomainSnapshotListAllChildren domainSnapshotListAllChildren;
     virDrvDomainSnapshotLookupByName    domainSnapshotLookupByName;
diff --git a/src/libvirt.c b/src/libvirt.c
index 3c4bf8c..7cb1c58 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -7380,6 +7380,104 @@ error:
 }
 
 /**
+ * virDomainInterfacesAddresses:
+ * @dom: domain object
+ * @ifaces: array of @dom interfaces
+ * @flags: bitwise-OR of virDomainInterfacesAddressesFlags
+ *
+ * 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 then returned.
+ *
+ * Note that for some combination of @flags and 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;
+ * int ifaces_count = 0;
+ * int i, j;
+ * virDomainPtr dom = ... obtain a domain here ...;
+ *
+ * ifaces_count = virDomainInterfacesAddresses(dom, &ifaces, 0);
+ * if (ifaces_count < 0) {
+ *     reportError();
+ *     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: the number of item in @ifaces,
+ *         -1 in case of error
+ */
+int
+virDomainInterfacesAddresses (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__);
+        goto error;
+    }
+
+    conn = dom->conn;
+
+    virCheckNonNullArgGoto(ifaces, error);
+
+    if (conn->driver->domainInterfacesAddresses) {
+        int ret;
+        ret = conn->driver->domainInterfacesAddresses(dom, ifaces, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibDomainError(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 e3ba119..8649f04 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -549,6 +549,7 @@ LIBVIRT_0.10.0 {
         virDomainGetHostname;
         virConnectRegisterCloseCallback;
         virConnectUnregisterCloseCallback;
+        virDomainInterfacesAddresses;
 } LIBVIRT_0.9.13;
 
 # .... define new API here using predicted next version number ....
-- 
1.7.8.6




More information about the libvir-list mailing list