[libvirt] [PATCH 1/5] lib: Add public api to enable atomic listing of guest

Peter Krempa pkrempa at redhat.com
Sun May 20 15:56:22 UTC 2012


This patch adds a new public api that lists domains. The new approach is
different from those used before. There are four key points to this:

1) The list is acquired atomicaly and contains both active and inactive
domains (guests). This eliminates the need to call two different list
APIs, where the state might change in between of the calls.

2) The returned list consists of virDomainPtrs instead of names or ID's
that have to be converted to virDomainPtrs anyways using separate calls
for each one of them. This is more convenient and saves resources and
application code in most (all?) cases.

3) The returned list is auto-allocated. This saves a lot hassle for the
users.

4) The python binding returns a list of domain objects that is very neat
to work with.

The only problem with this approach is no support from code generators
so both RPC code and python bindings had to be written manualy.

*include/libvirt/libvirt.h.in: - add API prototype
                               - clean up whitespace mistakes nearby
*python/generator.py: - inhibit generation of the bindings for the new
                        api
*src/driver.h: - add driver prototype
               - clean up some whitespace mistakes nearby
*src/libvirt.c: - add public implementation
*src/libvirt_public.syms: - export the new symbol
---
 include/libvirt/libvirt.h.in |    8 +++++-
 python/generator.py          |    1 +
 src/driver.h                 |   12 ++++++++--
 src/libvirt.c                |   46 ++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |    5 ++++
 5 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a817db8..2dacd45 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1759,8 +1759,12 @@ int                     virDomainUndefineFlags   (virDomainPtr domain,
                                                   unsigned int flags);
 int                     virConnectNumOfDefinedDomains  (virConnectPtr conn);
 int                     virConnectListDefinedDomains (virConnectPtr conn,
-                                                 char **const names,
-                                                 int maxnames);
+                                                      char **const names,
+                                                      int maxnames);
+int                     virConnectListAllDomains (virConnectPtr conn,
+                                                  virDomainPtr **domains,
+                                                  int ndomains,
+                                                  unsigned int flags);
 int                     virDomainCreate         (virDomainPtr domain);
 int                     virDomainCreateWithFlags (virDomainPtr domain,
                                                  unsigned int flags);
diff --git a/python/generator.py b/python/generator.py
index 9530867..a81fe4d 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -453,6 +453,7 @@ skip_function = (
     'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
     'virSaveLastError', # We have our own python error wrapper
     'virFreeError', # Only needed if we use virSaveLastError
+    'virConnectListAllDomains', #overriden in virConnect.py

     'virStreamRecvAll', # Pure python libvirt-override-virStream.py
     'virStreamSendAll', # Pure python libvirt-override-virStream.py
diff --git a/src/driver.h b/src/driver.h
index 03d249b..d5c5072 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -251,9 +251,14 @@ typedef char *
                                            const char *domainXml,
                                            unsigned int flags);
 typedef int
-        (*virDrvListDefinedDomains)	(virConnectPtr conn,
-                                         char **const names,
-                                         int maxnames);
+        (*virDrvListDefinedDomains) (virConnectPtr conn,
+                                     char **const names,
+                                     int maxnames);
+typedef int
+        (*virDrvConnectListAllDomains) (virConnectPtr conn,
+                                        virDomainPtr **domains,
+                                        int ndomains,
+                                        unsigned int flags);
 typedef int
         (*virDrvNumOfDefinedDomains)	(virConnectPtr conn);
 typedef int
@@ -1014,6 +1019,7 @@ struct _virDriver {
     virDrvDomainGetDiskErrors domainGetDiskErrors;
     virDrvDomainSetMetadata domainSetMetadata;
     virDrvDomainGetMetadata domainGetMetadata;
+    virDrvConnectListAllDomains connectListAllDomains;
 };

 typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index 22fc863..09a6d95 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -8128,6 +8128,52 @@ error:
 }

 /**
+ * virConnectListAllDomains:
+ * @conn: Pointer to the hypervisor connection.
+ * @domains: Pointer to a variable to store the array containing domain objects
+ *           or NULL if the list is not required (just returns number of guests).
+ * @ndomains: Maximum number of requested guests. Set to -1 for no limits.
+ * @flags: Not used yet. Callers must pass 0.
+ *
+ * List all guests (domains). This function allocates and returns a complete list
+ * of guests. Caller has to free the returned virDomainPtrs and the array.
+ *
+ * Returns number of guests found (and stored in *domains) or -1 on error.
+ */
+int
+virConnectListAllDomains(virConnectPtr conn,
+                         virDomainPtr **domains,
+                         int ndomains,
+                         unsigned int flags)
+{
+    VIR_DEBUG("conn=%p, domains=%p, ndomains=%d, flags=%x",
+              conn, domains, ndomains, flags);
+
+    virResetLastError();
+
+    if (!VIR_IS_CONNECT(conn)) {
+        virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__);
+        virDispatchError(NULL);
+        return -1;
+    }
+
+    if (conn->driver->connectListAllDomains) {
+        int ret;
+        ret = conn->driver->connectListAllDomains(conn, domains,
+                                                  ndomains, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(conn);
+    return -1;
+}
+
+/**
  * virDomainCreate:
  * @domain: pointer to a defined domain
  *
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 46c13fb..6fd4843 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:
+        virConnectListAllDomains;
+} LIBVIRT_0.9.11;
+
 # .... define new API here using predicted next version number ....
-- 
1.7.3.4




More information about the libvir-list mailing list