[libvirt] [PATCH] Add a trivial example program

David Allan dallan at redhat.com
Wed Feb 25 20:12:58 UTC 2009


This example code illustrates connecting to the hypervisor and making some simple API calls.

Added a little code to let the user specify the URI of the hypervisor on the command line, per the suggestion of Rich Jones.

Changes per Jim Meyering

Handle failure of virConnectNumOfDomains and virConnectNumOfDefinedDomains
Changed malloc to use size of variable, not type
Removed unneeded NULL check before free
Removed unneeded initialization of several variables
Changed assignment to use the ternary operator

Added examples/hellolibvirt to the parent autoconf/automake files and created Makefile.am

Add showError function to display error data generated by libvirt.
---
 Makefile.am                          |    2 +-
 configure.in                         |    3 +-
 examples/hellolibvirt/Makefile.am    |    5 +
 examples/hellolibvirt/hellolibvirt.c |  205 ++++++++++++++++++++++++++++++++++
 4 files changed, 213 insertions(+), 2 deletions(-)
 create mode 100644 examples/hellolibvirt/Makefile.am
 create mode 100644 examples/hellolibvirt/hellolibvirt.c

diff --git a/Makefile.am b/Makefile.am
index d4e42f1..928a93c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ LCOV = lcov
 GENHTML = genhtml
 
 SUBDIRS = gnulib/lib include src qemud proxy docs gnulib/tests \
-  python tests po examples/domain-events/events-c
+  python tests po examples/domain-events/events-c examples/hellolibvirt
 
 ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4
 
diff --git a/configure.in b/configure.in
index 6e04d56..d1718c7 100644
--- a/configure.in
+++ b/configure.in
@@ -1286,7 +1286,8 @@ AC_OUTPUT(Makefile src/Makefile include/Makefile docs/Makefile \
           tests/xmconfigdata/Makefile \
           tests/xencapsdata/Makefile \
           tests/confdata/Makefile \
-          examples/domain-events/events-c/Makefile)
+          examples/domain-events/events-c/Makefile \
+          examples/hellolibvirt/Makefile)
 
 AC_MSG_NOTICE([])
 AC_MSG_NOTICE([Configuration summary])
diff --git a/examples/hellolibvirt/Makefile.am b/examples/hellolibvirt/Makefile.am
new file mode 100644
index 0000000..6ef2cc8
--- /dev/null
+++ b/examples/hellolibvirt/Makefile.am
@@ -0,0 +1,5 @@
+INCLUDES = -I at top_srcdir@/include
+noinst_PROGRAMS = hellolibvirt
+hellolibvirt_CFLAGS = $(WARN_CFLAGS)
+hellolibvirt_SOURCES = hellolibvirt.c
+hellolibvirt_LDADD = @top_builddir@/src/libvirt.la
diff --git a/examples/hellolibvirt/hellolibvirt.c b/examples/hellolibvirt/hellolibvirt.c
new file mode 100644
index 0000000..234637e
--- /dev/null
+++ b/examples/hellolibvirt/hellolibvirt.c
@@ -0,0 +1,205 @@
+/* This file contains trivial example code to connect to the running
+ * hypervisor and gather a few bits of information.  */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
+static void
+showError(virConnectPtr conn)
+{
+    int ret;
+    virErrorPtr err;
+
+    err = malloc(sizeof(*err));
+    if (NULL == err) {
+        printf("Could not allocate memory for error data\n");
+        goto out;
+    }
+
+    ret = virConnCopyLastError(conn, err);
+
+    switch (ret) {
+    case 0:
+        printf("No error found\n");
+        break;
+
+    case -1:
+        printf("Parameter error when attempting to get last error\n");
+        break;
+
+    default:
+        printf("libvirt reported: \"%s\"\n", err->message);
+        break;
+    }
+
+    virResetError(err);
+    free(err);
+
+out:
+    return;
+}
+
+
+static int
+showHypervisorInfo(virConnectPtr conn)
+{
+    int ret = 0;
+    unsigned long hvVer, major, minor, release;
+    const char *hvType;
+
+    /* virConnectGetType returns a pointer to a static string, so no
+     * allocation or freeing is necessary; it is possible for the call
+     * to fail if, for example, there is no connection to a
+     * hypervisor, so check what it returns. */
+    hvType = virConnectGetType(conn);
+    if (NULL == hvType) {
+        ret = 1;
+        printf("Failed to get hypervisor type\n");
+        showError(conn);
+        goto out;
+    }
+
+    if (0 != virConnectGetVersion(conn, &hvVer)) {
+        ret = 1;
+        printf("Failed to get hypervisor version\n");
+        showError(conn);
+        goto out;
+    }
+
+    major = hvVer / 1000000;
+    hvVer %= 1000000;
+    minor = hvVer / 1000;
+    release = hvVer % 1000;
+
+    printf("Hypervisor: \"%s\" version: %lu.%lu.%lu\n",
+           hvType,
+           major,
+           minor,
+           release);
+
+out:
+    return ret;
+}
+
+
+static int
+showDomains(virConnectPtr conn)
+{
+    int ret = 0, i, numNames, numInactiveDomains, numActiveDomains;
+    char **nameList = NULL;
+
+    numActiveDomains = virConnectNumOfDomains(conn);
+    if (-1 == numActiveDomains) {
+        ret = 1;
+        printf("Failed to get number of active domains\n");
+        showError(conn);
+        goto out;
+    }
+
+    numInactiveDomains = virConnectNumOfDefinedDomains(conn);
+    if (-1 == numInactiveDomains) {
+        ret = 1;
+        printf("Failed to get number of inactive domains\n");
+        showError(conn);
+        goto out;
+    }
+
+    printf("There are %d active and %d inactive domains\n",
+           numActiveDomains, numInactiveDomains);
+
+    nameList = malloc(sizeof(*nameList) * numInactiveDomains);
+
+    if (NULL == nameList) {
+        ret = 1;
+        printf("Could not allocate memory for list of inactive domains\n");
+        goto out;
+    }
+
+    numNames = virConnectListDefinedDomains(conn,
+                                            nameList,
+                                            numInactiveDomains);
+
+    if (-1 == numNames) {
+        ret = 1;
+        printf("Could not get list of defined domains from hypervisor\n");
+        showError(conn);
+        goto out;
+    }
+
+    if (numNames > 0) {
+        printf("Inactive domains:\n");
+    }
+
+    for (i = 0 ; i < numNames ; i++) {
+        printf("  %s\n", *(nameList + i));
+        /* The API documentation doesn't say so, but the names
+         * returned by virConnectListDefinedDomains are strdup'd and
+         * must be freed here.  */
+        free(*(nameList + i));
+    }
+
+out:
+    free(nameList);
+    return ret;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+    int ret = 0;
+    virConnectPtr conn;
+    char *uri;
+
+    printf("Attempting to connect to hypervisor\n");
+
+    uri = (argc > 0 ? argv[1] : NULL);
+
+    /* virConnectOpenAuth is called here with all default parameters,
+     * except, possibly, the URI of the hypervisor. */
+    conn = virConnectOpenAuth(uri, virConnectAuthPtrDefault, 0);
+
+    if (NULL == conn) {
+        ret = 1;
+        printf("No connection to hypervisor\n");
+        showError(conn);
+        goto out;
+    }
+
+    uri = virConnectGetURI(conn);
+    if (NULL == uri) {
+        ret = 1;
+        printf("Failed to get URI for hypervisor connection\n");
+        showError(conn);
+        goto disconnect;
+    }
+
+    printf("Connected to hypervisor at \"%s\"\n", uri);
+    free(uri);
+
+    if (0 != showHypervisorInfo(conn)) {
+        ret = 1;
+        goto disconnect;
+    }
+
+    if (0 != showDomains(conn)) {
+        ret = 1;
+        goto disconnect;
+    }
+
+disconnect:
+    if (0 != virConnectClose(conn)) {
+        printf("Failed to disconnect from hypervisor\n");
+        showError(conn);
+        ret = 1;
+    } else {
+        printf("Disconnected from hypervisor\n");
+    }
+
+out:
+    return ret;
+}
-- 
1.6.0.6




More information about the libvir-list mailing list