[libvirt] [PATCH 2/3] examples: admin: Add some examples for the new admin APIs

Erik Skultety eskultet at redhat.com
Fri Jun 24 18:34:18 UTC 2016


Some of the examples make use of asprintf and strtol functions (to keep
things simple) which are prohibited to use within our code (enforced by
syntax-check). Therefore besides adding some examples, this patch also updates
cfg.mk to exclude examples directory from asprintf and strtol rules, as well as
updates .gitignore to exclude all the new admin binaries created in the
'examples' dir.

Signed-off-by: Erik Skultety <eskultet at redhat.com>
---
 .gitignore                         |   6 ++
 cfg.mk                             |   4 +-
 examples/Makefile.am               |  14 +++-
 examples/admin/client_close.c      |  57 +++++++++++++
 examples/admin/client_info.c       | 165 +++++++++++++++++++++++++++++++++++++
 examples/admin/client_limits.c     |  63 ++++++++++++++
 examples/admin/list_clients.c      | 111 +++++++++++++++++++++++++
 examples/admin/list_servers.c      |  42 ++++++++++
 examples/admin/threadpool_params.c |  65 +++++++++++++++
 9 files changed, 523 insertions(+), 4 deletions(-)
 create mode 100644 examples/admin/client_close.c
 create mode 100644 examples/admin/client_info.c
 create mode 100644 examples/admin/client_limits.c
 create mode 100644 examples/admin/list_clients.c
 create mode 100644 examples/admin/list_servers.c
 create mode 100644 examples/admin/threadpool_params.c

diff --git a/.gitignore b/.gitignore
index fba1464..e87c085 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,6 +74,12 @@
 /docs/libvirt-refs.xml
 /docs/search.php
 /docs/todo.html.in
+/examples/admin/client_close
+/examples/admin/client_info
+/examples/admin/client_limits
+/examples/admin/list_clients
+/examples/admin/list_servers
+/examples/admin/threadpool_params
 /examples/object-events/event-test
 /examples/dominfo/info1
 /examples/domsuspend/suspend
diff --git a/cfg.mk b/cfg.mk
index 0475bd9..cf47d4c 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -1147,7 +1147,7 @@ exclude_file_name_regexp--sc_prohibit_access_xok = \
 	^(cfg\.mk|src/util/virutil\.c)$$
 
 exclude_file_name_regexp--sc_prohibit_asprintf = \
-  ^(cfg\.mk|bootstrap.conf$$|src/util/virstring\.[ch]$$|tests/vircgroupmock\.c$$)
+  ^(cfg\.mk|bootstrap.conf$$|examples/|src/util/virstring\.[ch]$$|tests/vircgroupmock\.c$$)
 
 exclude_file_name_regexp--sc_prohibit_strdup = \
   ^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.c$$)
@@ -1189,7 +1189,7 @@ exclude_file_name_regexp--sc_prohibit_sprintf = \
 
 exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virstring\.c$$
 
-exclude_file_name_regexp--sc_prohibit_strtol = ^examples/dom.*/.*\.c$$
+exclude_file_name_regexp--sc_prohibit_strtol = ^examples/.*$$
 
 exclude_file_name_regexp--sc_prohibit_gethostby = ^docs/nss.html.in$$
 
diff --git a/examples/Makefile.am b/examples/Makefile.am
index e1c37f0..bd8460d 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -37,11 +37,14 @@ EXTRA_DIST = \
 INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir) \
 	-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib
 LDADD = $(STATIC_BINARIES) $(WARN_CFLAGS) $(COVERAGE_LDFLAGS) \
-	$(top_builddir)/src/libvirt.la $(top_builddir)/gnulib/lib/libgnu.la
+	$(top_builddir)/src/libvirt.la $(top_builddir)/gnulib/lib/libgnu.la \
+	$(top_builddir)/src/libvirt-admin.la
 
 noinst_PROGRAMS=dominfo/info1 dommigrate/dommigrate domsuspend/suspend \
 	domtop/domtop hellolibvirt/hellolibvirt object-events/event-test \
-	openauth/openauth rename/rename
+	openauth/openauth rename/rename admin/list_servers admin/list_clients \
+	admin/threadpool_params admin/client_limits admin/client_info \
+	admin/client_close
 
 dominfo_info1_SOURCES = dominfo/info1.c
 dommigrate_dommigrate_SOURCES = dommigrate/dommigrate.c
@@ -57,6 +60,13 @@ object_events_event_test_SOURCES = object-events/event-test.c
 openauth_openauth_SOURCES = openauth/openauth.c
 rename_rename_SOURCES = rename/rename.c
 
+admin_list_servers_SOURCES = admin/list_servers.c
+admin_list_clients_SOURCES = admin/list_clients.c
+admin_threadpool_params_SOURCES = admin/threadpool_params.c
+admin_client_limits_SOURCES = admin/client_limits.c
+admin_client_info_SOURCES = admin/client_info.c
+admin_client_close_SOURCES = admin/client_close.c
+
 if WITH_APPARMOR_PROFILES
 apparmordir = $(sysconfdir)/apparmor.d/
 apparmor_DATA = \
diff --git a/examples/admin/client_close.c b/examples/admin/client_close.c
new file mode 100644
index 0000000..a392707
--- /dev/null
+++ b/examples/admin/client_close.c
@@ -0,0 +1,57 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<libvirt/libvirt.h>
+#include<libvirt/libvirt-admin.h>
+
+int main(void)
+{
+    int ret = -1;
+    virAdmConnectPtr conn1 = NULL; /* admin connection */
+    virConnectPtr conn2 = NULL;    /* libvirt standard connection */
+    virAdmServerPtr srv = NULL;    /* which server is the client connected to */
+    virAdmClientPtr clnt = NULL;   /* which client to disconnect */
+
+    /* first, open a standard libvirt connection to the daemon */
+    if (!(conn2 = virConnectOpen(NULL)))
+        return -1;
+
+    /* next, open an admin connection that will be used to disconnect the
+     * standard libvirt client
+     */
+    if (!(conn1 = virAdmConnectOpen(NULL, 0)))
+        goto cleanup;
+
+    /* a virAdmServerPtr handle is needed, so a server lookup is performed */
+    if (!(srv = virAdmConnectLookupServer(conn1, "libvirtd", 0)))
+        goto cleanup;
+
+    /* a virAdmClientPtr handle is also necessary, so lookup for client is
+     * performed as well
+     */
+    if (!(clnt = virAdmServerLookupClient(srv, 1, 0)))
+        goto cleanup;
+
+    /* finally, use the client handle to disconnect the standard libvirt client
+     * from libvirtd daemon
+     */
+    if (virAdmClientClose(clnt, 0) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    /* Once finished, both server and client handles need to be freed and
+     * both connections @conn1 and @conn2 should be closed to free the
+     * memory.
+     * NOTE: Although @conn2 has been disconnected, unlike disconnecting by
+     * calling virConnectClose which closes the connection voluntarily and
+     * frees the object automatically, virAdmClientClose is a forceful
+     * disconnect of another client (client can use it on itself as well).
+     * Therefore no automatic deallocation of the object takes place and is
+     * the callers responsibility to do so.
+     */
+    virAdmClientFree(clnt);
+    virAdmServerFree(srv);
+    virAdmConnectClose(conn1);
+    virConnectClose(conn2);
+    return ret;
+}
diff --git a/examples/admin/client_info.c b/examples/admin/client_info.c
new file mode 100644
index 0000000..dd0a04a
--- /dev/null
+++ b/examples/admin/client_info.c
@@ -0,0 +1,165 @@
+#define _GNU_SOURCE
+#include<stdio.h>
+#include<stdlib.h>
+#include<time.h>
+#include<string.h>
+#include<libvirt/libvirt-admin.h>
+
+static const char *
+exampleTransportToString(int transport)
+{
+    const char *str = NULL;
+
+    switch ((virClientTransport) transport) {
+    case VIR_CLIENT_TRANS_UNIX:
+        str = "unix";
+        break;
+    case VIR_CLIENT_TRANS_TCP:
+        str = "tcp";
+        break;
+    case VIR_CLIENT_TRANS_TLS:
+        str = "tls";
+        break;
+    }
+
+    return str ? str : "unknown";
+}
+
+static char *
+exampleGetTimeStr(time_t then)
+{
+    char *ret = NULL;
+    struct tm timeinfo;
+
+    if (!localtime_r(&then, &timeinfo))
+        return NULL;
+
+    if (!(ret = calloc(64, sizeof(char))))
+        return NULL;
+
+    if (strftime(ret, 64, "%Y-%m-%d %H:%M:%S%z",
+                 &timeinfo) == 0) {
+        free(ret);
+        return NULL;
+    }
+
+    return ret;
+}
+
+static char *
+exampleGetTypedParamValue(virTypedParameterPtr item)
+{
+    int ret = 0;
+    char *str = NULL;
+
+    switch (item->type) {
+    case VIR_TYPED_PARAM_INT:
+        ret = asprintf(&str, "%d", item->value.i);
+        break;
+
+    case VIR_TYPED_PARAM_UINT:
+        ret = asprintf(&str, "%u", item->value.ui);
+        break;
+
+    case VIR_TYPED_PARAM_LLONG:
+        ret = asprintf(&str, "%lld", item->value.l);
+        break;
+
+    case VIR_TYPED_PARAM_ULLONG:
+        ret = asprintf(&str, "%llu", item->value.ul);
+        break;
+
+    case VIR_TYPED_PARAM_DOUBLE:
+        ret = asprintf(&str, "%f", item->value.d);
+        break;
+
+    case VIR_TYPED_PARAM_BOOLEAN:
+        str = strdup(item->value.b ? "yes" : "no");
+        break;
+
+    case VIR_TYPED_PARAM_STRING:
+        str = strdup(item->value.s);
+        break;
+
+    default:
+        fprintf(stderr, "unimplemented parameter type %d\n", item->type);
+        return NULL;
+    }
+
+    return str;
+}
+
+int main(int argc, char **argv)
+{
+    int ret = -1;
+    virAdmConnectPtr conn = NULL;
+    virAdmServerPtr srv = NULL;    /* which server is the client connected to */
+    virAdmClientPtr clnt = NULL;   /* which client get identity for */
+    virTypedParameterPtr params = NULL;     /* where to store identity info */
+    int nparams = 0;
+    size_t i = 0;
+    char *timestr = NULL;
+
+    if (argc != 3) {
+        fprintf(stderr, "Two arguments, first specifying the server client is "
+                "connected to and second, specifying the client's ID for which "
+                "identity information should be retrieved, are expected\n");
+        return -1;
+    }
+
+    /* first, open a connection to the daemon */
+    if (!(conn = virAdmConnectOpen(NULL, 0)))
+        return -1;
+
+    /* first a virAdmServerPtr handle is necessary to obtain, that is done by
+     * doing a lookup for specific server, argv[1] holds the server name
+     */
+    if (!(srv = virAdmConnectLookupServer(conn, argv[1], 0)))
+        goto cleanup;
+
+    /* next, virAdmClientPtr handle is necessary to obtain, that is done by
+     * doing a lookup on a specific server, argv[2] holds the client's ID
+     */
+    if (!(clnt = virAdmServerLookupClient(srv, strtoll(argv[2], NULL, 10), 0)))
+        goto cleanup;
+
+    /* finally, retrieve @clnt's identity information */
+    if (virAdmClientGetInfo(clnt, &params, &nparams, 0) < 0)
+        goto cleanup;
+
+    /* this information is provided by the client object itself, not by typed
+     * params container; it is unnecessary to call virAdmClientGetInfo if only
+     * ID, transport method, and timestamp are the required data
+     */
+    if (!(timestr = exampleGetTimeStr(virAdmClientGetTimestamp(clnt))))
+        goto cleanup;
+
+    printf("%-15s: %llu\n", "id", virAdmClientGetID(clnt));
+    printf("%-15s: %s\n", "connection_time", timestr);
+    printf("%-15s: %s\n", "transport",
+             exampleTransportToString(virAdmClientGetTransport(clnt)));
+
+    /* this is the actual identity information retrieved in typed params
+     * container
+     */
+    for (i = 0; i < nparams; i++) {
+        char *str = NULL;
+        if (!(str = exampleGetTypedParamValue(&params[i])))
+            goto cleanup;
+        printf("%-15s: %s\n", params[i].field, str);
+        free(str);
+    }
+
+    ret = 0;
+ cleanup:
+    /* Once finished, free the typed params container, server and client
+     * handles and close the connection properly, @conn will be deallocated
+     * automatically
+     */
+    virTypedParamsFree(params, nparams);
+    virAdmClientFree(clnt);
+    virAdmServerFree(srv);
+    virAdmConnectClose(conn);
+    free(timestr);
+    return ret;
+}
diff --git a/examples/admin/client_limits.c b/examples/admin/client_limits.c
new file mode 100644
index 0000000..2d5b754
--- /dev/null
+++ b/examples/admin/client_limits.c
@@ -0,0 +1,63 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<libvirt/libvirt-admin.h>
+
+int main(int argc, char **argv)
+{
+    int ret = -1;
+    virAdmConnectPtr conn = NULL;
+    virAdmServerPtr srv = NULL;     /* which server to work with */
+    virTypedParameterPtr params = NULL;
+    int nparams = 0;
+    size_t i;
+
+    if (argc != 2) {
+        fprintf(stderr, "One argument specifying the server which to work "
+                "with is expected\n");
+        return -1;
+    }
+
+    /* first, open a connection to the daemon */
+    if (!(conn = virAdmConnectOpen(NULL, 0)))
+        goto cleanup;
+
+    /* a server handle is necessary before any API regarding threadpool
+     * parameters can be issued
+     */
+    if (!(srv = virAdmConnectLookupServer(conn, argv[1], 0)))
+        goto cleanup;
+
+    /* get the current client limits */
+    if (virAdmServerGetClientLimits(srv, &params, &nparams, 0) < 0)
+        goto cleanup;
+
+    for (i = 0; i < nparams; i++)
+        printf("%-15s: %d\n", params[i].field, params[i].value.ui);
+
+    virTypedParamsFree(params, nparams);
+    params = NULL;
+    nparams = 0;
+
+    /* set nclients_max to 100 and nclients_unauth_max to 20 */
+    int maxparams = 0;
+    if (virTypedParamsAddUInt(&params, &nparams, &maxparams,
+                              VIR_SERVER_CLIENTS_MAX, 100) < 0 ||
+        virTypedParamsAddUInt(&params, &nparams, &maxparams,
+                              VIR_SERVER_CLIENTS_UNAUTH_MAX, 20) < 0)
+        goto cleanup;
+
+    /* now, change the client limits on the server */
+    if (virAdmServerSetClientLimits(srv, params, nparams, 0) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virTypedParamsFree(params, nparams);
+
+    /* Once finished deallocate the server handle and close the connection
+     * properly, @conn will be deallocated automatically
+     */
+    virAdmServerFree(srv);
+    virAdmConnectClose(conn);
+    return ret;
+}
diff --git a/examples/admin/list_clients.c b/examples/admin/list_clients.c
new file mode 100644
index 0000000..3b4496e
--- /dev/null
+++ b/examples/admin/list_clients.c
@@ -0,0 +1,111 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<time.h>
+#include<libvirt/libvirt-admin.h>
+
+static const char *
+exampleTransportToString(int transport)
+{
+    const char *str = NULL;
+
+    switch ((virClientTransport) transport) {
+    case VIR_CLIENT_TRANS_UNIX:
+        str = "unix";
+        break;
+    case VIR_CLIENT_TRANS_TCP:
+        str = "tcp";
+        break;
+    case VIR_CLIENT_TRANS_TLS:
+        str = "tls";
+        break;
+    }
+
+    return str ? str : "unknown";
+}
+
+static char *
+exampleGetTimeStr(time_t then)
+{
+    char *ret = NULL;
+    struct tm timeinfo;
+
+    if (!localtime_r(&then, &timeinfo))
+        return NULL;
+
+    if (!(ret = calloc(64, sizeof(char))))
+        return NULL;
+
+    if (strftime(ret, 64, "%Y-%m-%d %H:%M:%S%z",
+                 &timeinfo) == 0) {
+        free(ret);
+        return NULL;
+    }
+
+    return ret;
+}
+
+int main(int argc, char **argv)
+{
+    int ret = -1;
+    virAdmConnectPtr conn = NULL;
+    virAdmServerPtr srv = NULL;      /* which server list the clients from */
+    virAdmClientPtr *clients = NULL;    /* where to store the servers */
+    size_t i = 0;
+    int count = 0;
+
+    if (argc != 2) {
+        fprintf(stderr, "One argument specifying the server to list connected "
+                "clients for is expected\n");
+        return -1;
+    }
+
+    /* first, open a connection to the daemon */
+    if (!(conn = virAdmConnectOpen(NULL, 0)))
+        return -1;
+
+    /* first a virAdmServerPtr handle is necessary to obtain, that is done by
+     * doing a lookup for specific server, let's get a handle on "libvirtd"
+     * server
+     */
+    if (!(srv = virAdmConnectLookupServer(conn, argv[1], 0)))
+        goto cleanup;
+
+    /* now get the currently connected clients to server @srv */
+    if ((count = virAdmServerListClients(srv, &clients, 0)) < 0)
+        goto cleanup;
+
+    /* let's print the currently connected clients and some basic info about
+     * them, we have 2 options how to interate over the returned list,
+     * use @count as the boundary or use the fact that @clients are guaranteed
+     * to contain 1 extra element NULL;
+     * this example uses the first option
+     */
+    printf(" %-5s %-15s %-15s\n%s\n", "Id", "Transport", "Connected since",
+           "--------------------------------------------------");
+
+    for (i = 0; i < count; i++) {
+        virAdmClientPtr client = clients[i];
+        unsigned long long id = virAdmClientGetID(client);
+        int transport = virAdmClientGetTransport(client);
+        char * timestr = NULL;
+        if (!(timestr =
+                exampleGetTimeStr(virAdmClientGetTimestamp(client))))
+            goto cleanup;
+
+        printf(" %-5llu %-15s %-15s\n", id,
+               exampleTransportToString(transport), timestr);
+        free(timestr);
+    }
+
+    ret = 0;
+ cleanup:
+    /* Once finished, free the list of clients, free the server handle and
+     * close the connection properly, @conn will be deallocated automatically
+     */
+    for (i = 0; i < count; i++)
+        virAdmClientFree(clients[i]);
+    free(clients);
+    virAdmServerFree(srv);
+    virAdmConnectClose(conn);
+    return ret;
+}
diff --git a/examples/admin/list_servers.c b/examples/admin/list_servers.c
new file mode 100644
index 0000000..1f6f4c6
--- /dev/null
+++ b/examples/admin/list_servers.c
@@ -0,0 +1,42 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<libvirt/libvirt-admin.h>
+
+int main(void)
+{
+    int ret = -1;
+    virAdmConnectPtr conn = NULL;
+    virAdmServerPtr *servers = NULL;    /* where to store the servers */
+    virAdmServerPtr *tmp = NULL;
+    size_t i = 0;
+    int count = 0;
+
+    /* first, open a connection to the daemon */
+    if (!(conn = virAdmConnectOpen(NULL, 0)))
+        goto cleanup;
+
+    /* get the available servers on the default daemon - libvirtd */
+    if ((count = virAdmConnectListServers(conn, &servers, 0)) < 0)
+        goto cleanup;
+
+    /* let's print the available servers, we have 2 options how to interate
+     * over the returned list, use @count as the boundary or use the fact
+     * that @servers are guaranteed to contain 1 extra element NULL;
+     * this example uses the second option
+     */
+    printf(" %-15s\n", "Server name");
+    printf("---------------\n");
+    for (tmp = servers; *tmp; tmp++)
+        printf(" %-15s\n", virAdmServerGetName(*tmp));
+
+    ret = 0;
+ cleanup:
+    /* Once finished, free the list of servers and close the connection
+     * properly, @conn will be deallocated automatically
+     */
+    for (i = 0; i < count; i++)
+        virAdmServerFree(servers[i]);
+    free(servers);
+    virAdmConnectClose(conn);
+    return ret;
+}
diff --git a/examples/admin/threadpool_params.c b/examples/admin/threadpool_params.c
new file mode 100644
index 0000000..ee9ce83
--- /dev/null
+++ b/examples/admin/threadpool_params.c
@@ -0,0 +1,65 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<libvirt/libvirt-admin.h>
+
+int main(int argc, char **argv)
+{
+    int ret = -1;
+    virAdmConnectPtr conn = NULL;
+    virAdmServerPtr srv = NULL;     /* which server to work with */
+    virTypedParameterPtr params = NULL;
+    int nparams = 0;
+    size_t i;
+
+    if (argc != 2) {
+        fprintf(stderr, "One argument specifying the server which to work "
+                "with is expected\n");
+        return -1;
+    }
+
+    /* first, open a connection to the daemon */
+    if (!(conn = virAdmConnectOpen(NULL, 0)))
+        goto cleanup;
+
+    /* a server handle is necessary before any API regarding threadpool
+     * parameters can be issued
+     */
+    if (!(srv = virAdmConnectLookupServer(conn, argv[1], 0)))
+        goto cleanup;
+
+    /* get the current threadpool parameters */
+    if (virAdmServerGetThreadPoolParameters(srv, &params, &nparams, 0) < 0)
+        goto cleanup;
+
+    for (i = 0; i < nparams; i++)
+        printf("%-15s: %d\n", params[i].field, params[i].value.ui);
+
+    virTypedParamsFree(params, nparams);
+    params = NULL;
+    nparams = 0;
+
+    /* let's set minWorkers to 10, maxWorkers to 15 and prioWorkers to 10 */
+    int maxparams = 0;
+    if (virTypedParamsAddUInt(&params, &nparams, &maxparams,
+                              VIR_THREADPOOL_WORKERS_MIN, 10) < 0 ||
+        virTypedParamsAddUInt(&params, &nparams, &maxparams,
+                              VIR_THREADPOOL_WORKERS_MAX, 15) < 0 ||
+        virTypedParamsAddUInt(&params, &nparams, &maxparams,
+                              VIR_THREADPOOL_WORKERS_PRIORITY, 10) < 0)
+        goto cleanup;
+
+    /* now, change the threadpool settings to some different values */
+    if (virAdmServerSetThreadPoolParameters(srv, params, nparams, 0) < 0)
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    virTypedParamsFree(params, nparams);
+
+    /* Once finished deallocate the server handle and close the connection
+     * properly, @conn will be deallocated automatically
+     */
+    virAdmServerFree(srv);
+    virAdmConnectClose(conn);
+    return ret;
+}
-- 
2.5.5




More information about the libvir-list mailing list