/docs/libvirt-refs.xml
/docs/news.html.in
/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/logging
-/examples/admin/threadpool_params
-/examples/domain/dommigrate
-/examples/domain/domtop
-/examples/domain/info1
-/examples/domain/rename
-/examples/domain/suspend
-/examples/misc/event-test
-/examples/misc/hellolibvirt
-/examples/misc/openauth
+/examples/c/admin/client_close
+/examples/c/admin/client_info
+/examples/c/admin/client_limits
+/examples/c/admin/list_clients
+/examples/c/admin/list_servers
+/examples/c/admin/logging
+/examples/c/admin/threadpool_params
+/examples/c/domain/dommigrate
+/examples/c/domain/domtop
+/examples/c/domain/info1
+/examples/c/domain/rename
+/examples/c/domain/suspend
+/examples/c/misc/event-test
+/examples/c/misc/hellolibvirt
+/examples/c/misc/openauth
/gnulib/lib/*
/gnulib/m4/*
/gnulib/tests/*
^src/rpc/gendispatch\.pl$$
exclude_file_name_regexp--sc_prohibit_nonreentrant = \
- ^((po|tests|examples/admin)/|docs/.*(py|js|html\.in)|run.in$$|tools/wireshark/util/genxdrstub\.pl$$)
+ ^((po|tests|examples)/|docs/.*(py|js|html\.in)|run.in$$|tools/wireshark/util/genxdrstub\.pl$$)
exclude_file_name_regexp--sc_prohibit_select = \
^cfg\.mk$$
FILTERS = $(wildcard $(srcdir)/xml/nwfilter/*.xml)
ADMIN_EXAMPLES = \
- $(wildcard $(srcdir)/admin/*.c) \
+ $(wildcard $(srcdir)/c/admin/*.c) \
$(NULL)
DOMAIN_EXAMPLES = \
- $(wildcard $(srcdir)/domain/*.c) \
+ $(wildcard $(srcdir)/c/domain/*.c) \
$(NULL)
MISC_EXAMPLES = \
- $(wildcard $(srcdir)/misc/*.c) \
+ $(wildcard $(srcdir)/c/misc/*.c) \
$(NULL)
POLKIT_EXAMPLES = \
$(NULL)
noinst_PROGRAMS = \
- admin/client_close \
- admin/client_info \
- admin/client_limits \
- admin/list_clients \
- admin/list_servers \
- admin/logging \
- admin/threadpool_params \
- domain/dommigrate \
- domain/domtop \
- domain/info1 \
- domain/rename \
- domain/suspend \
- misc/event-test \
- misc/hellolibvirt \
- misc/openauth \
+ c/admin/client_close \
+ c/admin/client_info \
+ c/admin/client_limits \
+ c/admin/list_clients \
+ c/admin/list_servers \
+ c/admin/logging \
+ c/admin/threadpool_params \
+ c/domain/dommigrate \
+ c/domain/domtop \
+ c/domain/info1 \
+ c/domain/rename \
+ c/domain/suspend \
+ c/misc/event-test \
+ c/misc/hellolibvirt \
+ c/misc/openauth \
$(NULL)
-admin_client_close_SOURCES = admin/client_close.c
-admin_client_info_SOURCES = admin/client_info.c
-admin_client_limits_SOURCES = admin/client_limits.c
-admin_list_clients_SOURCES = admin/list_clients.c
-admin_list_servers_SOURCES = admin/list_servers.c
-admin_logging_SOURCES = admin/logging.c
-admin_threadpool_params_SOURCES = admin/threadpool_params.c
-domain_dommigrate_SOURCES = domain/dommigrate.c
-domain_domtop_SOURCES = domain/domtop.c
-domain_info1_SOURCES = domain/info1.c
-domain_rename_SOURCES = domain/rename.c
-domain_suspend_SOURCES = domain/suspend.c
-misc_event_test_SOURCES = misc/event-test.c
-misc_hellolibvirt_SOURCES = misc/hellolibvirt.c
-misc_openauth_SOURCES = misc/openauth.c
+c_admin_client_close_SOURCES = c/admin/client_close.c
+c_admin_client_info_SOURCES = c/admin/client_info.c
+c_admin_client_limits_SOURCES = c/admin/client_limits.c
+c_admin_list_clients_SOURCES = c/admin/list_clients.c
+c_admin_list_servers_SOURCES = c/admin/list_servers.c
+c_admin_logging_SOURCES = c/admin/logging.c
+c_admin_threadpool_params_SOURCES = c/admin/threadpool_params.c
+c_domain_dommigrate_SOURCES = c/domain/dommigrate.c
+c_domain_domtop_SOURCES = c/domain/domtop.c
+c_domain_info1_SOURCES = c/domain/info1.c
+c_domain_rename_SOURCES = c/domain/rename.c
+c_domain_suspend_SOURCES = c/domain/suspend.c
+c_misc_event_test_SOURCES = c/misc/event-test.c
+c_misc_hellolibvirt_SOURCES = c/misc/hellolibvirt.c
+c_misc_openauth_SOURCES = c/misc/openauth.c
if WITH_NWFILTER
examplesdir = $(docdir)/examples
-adminexamplesdir = $(examplesdir)/admin
+adminexamplesdir = $(examplesdir)/c/admin
adminexamples_DATA = $(ADMIN_EXAMPLES)
-domainexamplesdir = $(examplesdir)/domain
+domainexamplesdir = $(examplesdir)/c/domain
domainexamples_DATA = $(DOMAIN_EXAMPLES)
-miscexamplesdir = $(examplesdir)/misc
+miscexamplesdir = $(examplesdir)/c/misc
miscexamples_DATA = $(MISC_EXAMPLES)
polkitexamplesdir = $(examplesdir)/polkit
+++ /dev/null
-#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;
-}
+++ /dev/null
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <string.h>
-#include <inttypes.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;
- struct tm *timeinfop;
-
- /* localtime_r() is smarter, but since mingw lacks it and this
- * example is single-threaded, we can get away with localtime */
- if (!(timeinfop = localtime(&then)))
- return NULL;
- timeinfo = *timeinfop;
-
- 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, "%" PRId64, (int64_t)item->value.l);
- break;
-
- case VIR_TYPED_PARAM_ULLONG:
- ret = asprintf(&str, "%" PRIu64, (uint64_t)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;
- }
-
- if (ret < 0) {
- fprintf(stderr, "error formatting typed param value\n");
- 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;
- ssize_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, ¶ms, &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: %" PRIu64 "\n", "id", (uint64_t)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(¶ms[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;
-}
+++ /dev/null
-#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;
- int maxparams = 0;
- ssize_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, ¶ms, &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 */
- if (virTypedParamsAddUInt(¶ms, &nparams, &maxparams,
- VIR_SERVER_CLIENTS_MAX, 100) < 0 ||
- virTypedParamsAddUInt(¶ms, &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;
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <inttypes.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;
- struct tm *timeinfop;
-
- /* localtime_r() is smarter, but since mingw lacks it and this
- * example is single-threaded, we can get away with localtime */
- if (!(timeinfop = localtime(&then)))
- return NULL;
- timeinfo = *timeinfop;
-
- 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 */
- ssize_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(" %-5" PRIu64 " %-15s %-15s\n", (uint64_t)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;
-}
+++ /dev/null
-#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;
- ssize_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;
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-#include <unistd.h>
-#include <libvirt/libvirt-admin.h>
-#include <libvirt/virterror.h>
-
-static void printHelp(const char *argv0)
-{
- fprintf(stderr,
- ("Usage:\n"
- " %s [options]\n"
- "\n"
- "Options:\n"
- " -h Print this message.\n"
- " -o [string] Specify new log outputs.\n"
- " -f [string] Specify new log filters.\n"
- "\n"),
- argv0);
-}
-
-int main(int argc, char **argv)
-{
- int ret, c;
- virAdmConnectPtr conn = NULL;
- char *get_outputs = NULL;
- char *get_filters = NULL;
- const char *set_outputs = NULL;
- const char *set_filters = NULL;
-
- ret = c = -1;
- opterr = 0;
-
- while ((c = getopt(argc, argv, ":hpo:f:")) > 0) {
- switch (c) {
- case 'h':
- printHelp(argv[0]);
- exit(EXIT_SUCCESS);
- case 'o':
- set_outputs = optarg;
- break;
- case 'f':
- set_filters = optarg;
- break;
- case ':':
- fprintf(stderr, "Missing argument for option -%c\n", optopt);
- exit(EXIT_FAILURE);
- case '?':
- fprintf(stderr, "Unrecognized option '-%c'\n", optopt);
- exit(EXIT_FAILURE);
- }
- }
-
- /* first, open a connection to the daemon */
- if (!(conn = virAdmConnectOpen(NULL, 0)))
- goto cleanup;
-
- /* get the currently defined log outputs and filters */
- if (virAdmConnectGetLoggingOutputs(conn, &get_outputs, 0) < 0 ||
- virAdmConnectGetLoggingFilters(conn, &get_filters, 0) < 0)
- goto cleanup;
-
- fprintf(stdout,
- "Current settings:\n"
- " outputs: %s\n"
- " filters: %s\n"
- "\n",
- get_outputs, get_filters ? get_filters : "None");
-
- free(get_outputs);
- free(get_filters);
-
- /* no arguments were provided */
- if (argc == 1) {
- ret = 0;
- goto cleanup;
- }
-
- /* now, try to change the redefine the current log output and filters */
- if (virAdmConnectSetLoggingOutputs(conn, set_outputs, 0) < 0)
- goto cleanup;
-
- if (virAdmConnectSetLoggingFilters(conn, set_filters, 0) < 0)
- goto cleanup;
-
- /* get the currently defined log outputs and filters */
- if (virAdmConnectGetLoggingOutputs(conn, &get_outputs, 0) < 0 ||
- virAdmConnectGetLoggingFilters(conn, &get_filters, 0) < 0)
- goto cleanup;
-
- fprintf(stdout,
- "New settings:\n"
- " outputs: %s\n"
- " filters: %s\n"
- "\n",
- get_outputs ? get_outputs : "Default",
- get_filters ? get_filters : "None");
-
- free(get_outputs);
- free(get_filters);
-
- ret = 0;
- cleanup:
- virAdmConnectClose(conn);
- return ret;
-}
+++ /dev/null
-#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;
- int maxparams = 0;
- ssize_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, ¶ms, &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 */
- if (virTypedParamsAddUInt(¶ms, &nparams, &maxparams,
- VIR_THREADPOOL_WORKERS_MIN, 10) < 0 ||
- virTypedParamsAddUInt(¶ms, &nparams, &maxparams,
- VIR_THREADPOOL_WORKERS_MAX, 15) < 0 ||
- virTypedParamsAddUInt(¶ms, &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;
-}
--- /dev/null
+#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;
+}
--- /dev/null
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <inttypes.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;
+ struct tm *timeinfop;
+
+ /* localtime_r() is smarter, but since mingw lacks it and this
+ * example is single-threaded, we can get away with localtime */
+ if (!(timeinfop = localtime(&then)))
+ return NULL;
+ timeinfo = *timeinfop;
+
+ 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, "%" PRId64, (int64_t)item->value.l);
+ break;
+
+ case VIR_TYPED_PARAM_ULLONG:
+ ret = asprintf(&str, "%" PRIu64, (uint64_t)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;
+ }
+
+ if (ret < 0) {
+ fprintf(stderr, "error formatting typed param value\n");
+ 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;
+ ssize_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, ¶ms, &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: %" PRIu64 "\n", "id", (uint64_t)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(¶ms[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;
+}
--- /dev/null
+#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;
+ int maxparams = 0;
+ ssize_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, ¶ms, &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 */
+ if (virTypedParamsAddUInt(¶ms, &nparams, &maxparams,
+ VIR_SERVER_CLIENTS_MAX, 100) < 0 ||
+ virTypedParamsAddUInt(¶ms, &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;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <inttypes.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;
+ struct tm *timeinfop;
+
+ /* localtime_r() is smarter, but since mingw lacks it and this
+ * example is single-threaded, we can get away with localtime */
+ if (!(timeinfop = localtime(&then)))
+ return NULL;
+ timeinfo = *timeinfop;
+
+ 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 */
+ ssize_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(" %-5" PRIu64 " %-15s %-15s\n", (uint64_t)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;
+}
--- /dev/null
+#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;
+ ssize_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;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <unistd.h>
+#include <libvirt/libvirt-admin.h>
+#include <libvirt/virterror.h>
+
+static void printHelp(const char *argv0)
+{
+ fprintf(stderr,
+ ("Usage:\n"
+ " %s [options]\n"
+ "\n"
+ "Options:\n"
+ " -h Print this message.\n"
+ " -o [string] Specify new log outputs.\n"
+ " -f [string] Specify new log filters.\n"
+ "\n"),
+ argv0);
+}
+
+int main(int argc, char **argv)
+{
+ int ret, c;
+ virAdmConnectPtr conn = NULL;
+ char *get_outputs = NULL;
+ char *get_filters = NULL;
+ const char *set_outputs = NULL;
+ const char *set_filters = NULL;
+
+ ret = c = -1;
+ opterr = 0;
+
+ while ((c = getopt(argc, argv, ":hpo:f:")) > 0) {
+ switch (c) {
+ case 'h':
+ printHelp(argv[0]);
+ exit(EXIT_SUCCESS);
+ case 'o':
+ set_outputs = optarg;
+ break;
+ case 'f':
+ set_filters = optarg;
+ break;
+ case ':':
+ fprintf(stderr, "Missing argument for option -%c\n", optopt);
+ exit(EXIT_FAILURE);
+ case '?':
+ fprintf(stderr, "Unrecognized option '-%c'\n", optopt);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* first, open a connection to the daemon */
+ if (!(conn = virAdmConnectOpen(NULL, 0)))
+ goto cleanup;
+
+ /* get the currently defined log outputs and filters */
+ if (virAdmConnectGetLoggingOutputs(conn, &get_outputs, 0) < 0 ||
+ virAdmConnectGetLoggingFilters(conn, &get_filters, 0) < 0)
+ goto cleanup;
+
+ fprintf(stdout,
+ "Current settings:\n"
+ " outputs: %s\n"
+ " filters: %s\n"
+ "\n",
+ get_outputs, get_filters ? get_filters : "None");
+
+ free(get_outputs);
+ free(get_filters);
+
+ /* no arguments were provided */
+ if (argc == 1) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ /* now, try to change the redefine the current log output and filters */
+ if (virAdmConnectSetLoggingOutputs(conn, set_outputs, 0) < 0)
+ goto cleanup;
+
+ if (virAdmConnectSetLoggingFilters(conn, set_filters, 0) < 0)
+ goto cleanup;
+
+ /* get the currently defined log outputs and filters */
+ if (virAdmConnectGetLoggingOutputs(conn, &get_outputs, 0) < 0 ||
+ virAdmConnectGetLoggingFilters(conn, &get_filters, 0) < 0)
+ goto cleanup;
+
+ fprintf(stdout,
+ "New settings:\n"
+ " outputs: %s\n"
+ " filters: %s\n"
+ "\n",
+ get_outputs ? get_outputs : "Default",
+ get_filters ? get_filters : "None");
+
+ free(get_outputs);
+ free(get_filters);
+
+ ret = 0;
+ cleanup:
+ virAdmConnectClose(conn);
+ return ret;
+}
--- /dev/null
+#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;
+ int maxparams = 0;
+ ssize_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, ¶ms, &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 */
+ if (virTypedParamsAddUInt(¶ms, &nparams, &maxparams,
+ VIR_THREADPOOL_WORKERS_MIN, 10) < 0 ||
+ virTypedParamsAddUInt(¶ms, &nparams, &maxparams,
+ VIR_THREADPOOL_WORKERS_MAX, 15) < 0 ||
+ virTypedParamsAddUInt(¶ms, &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;
+}
--- /dev/null
+/*
+ * dommigrate.c: This file is largely inspired from hellolibvirt and
+ * contains a trivial example that illustrate p2p domain
+ * migration with libvirt.
+ *
+ * Copyright (C) 2014 Cloudwatt
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
+
+static int
+usage(char *prgn, int ret)
+{
+ printf("Usage: %s <src uri> <dst uri> <domain name>\n", prgn);
+ return ret;
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *src_uri, *dst_uri, *domname;
+ int ret = 0;
+ virConnectPtr conn = NULL;
+ virDomainPtr dom = NULL;
+
+ if (argc < 4) {
+ ret = usage(argv[0], 1);
+ goto out;
+ }
+
+ src_uri = argv[1];
+ dst_uri = argv[2];
+ domname = argv[3];
+
+ printf("Attempting to connect to the source hypervisor...\n");
+ conn = virConnectOpenAuth(src_uri, virConnectAuthPtrDefault, 0);
+ if (!conn) {
+ ret = 1;
+ fprintf(stderr, "No connection to the source hypervisor: %s.\n",
+ virGetLastErrorMessage());
+ goto out;
+ }
+
+ printf("Attempting to retrieve domain %s...\n", domname);
+ dom = virDomainLookupByName(conn, domname);
+ if (!dom) {
+ fprintf(stderr, "Failed to find domain %s.\n", domname);
+ goto cleanup;
+ }
+
+ printf("Attempting to migrate %s to %s...\n", domname, dst_uri);
+ if ((ret = virDomainMigrateToURI(dom, dst_uri,
+ VIR_MIGRATE_PEER2PEER,
+ NULL, 0)) != 0) {
+ fprintf(stderr, "Failed to migrate domain %s.\n", domname);
+ goto cleanup;
+ }
+
+ printf("Migration finished with success.\n");
+
+ cleanup:
+ if (dom != NULL)
+ virDomainFree(dom);
+ virConnectClose(conn);
+
+ out:
+ return ret;
+}
--- /dev/null
+/*
+ * domtop.c: Demo program showing how to calculate CPU usage
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+static bool debug;
+static bool run_top;
+
+/* On mingw, there's a header file that poisons the well:
+ *
+ *
+ * CC domtop.o
+ *domtop.c:40:0: warning: "ERROR" redefined [enabled by default]
+ * #define ERROR(...) \
+ * ^
+ *In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/windows.h:71:0,
+ * from /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:23,
+ * from ../../gnulib/lib/unistd.h:48,
+ * from domtop.c:35:
+ * /usr/i686-w64-mingw32/sys-root/mingw/include/wingdi.h:75:0: note: this is the location of the previous definition
+ * #define ERROR 0
+ */
+#undef ERROR
+#define ERROR(...) \
+do { \
+ fprintf(stderr, "ERROR %s:%d : ", __FUNCTION__, __LINE__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+} while (0)
+
+#define DEBUG(...) \
+do { \
+ if (!debug) \
+ break; \
+ fprintf(stderr, "DEBUG %s:%d : ", __FUNCTION__, __LINE__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+} while (0)
+
+#define STREQ(a, b) (strcmp(a, b) == 0)
+
+static void
+print_usage(const char *progname)
+{
+ const char *unified_progname;
+
+ if (!(unified_progname = strrchr(progname, '/')))
+ unified_progname = progname;
+ else
+ unified_progname++;
+
+ printf("\n%s [options] [domain name]\n\n"
+ " options:\n"
+ " -d | --debug enable debug messages\n"
+ " -h | --help print this help\n"
+ " -c | --connect=URI hypervisor connection URI\n"
+ " -D | --delay=X delay between updates in milliseconds "
+ "(default is 500ms)\n"
+ "\n"
+ "Print the cumulative usage of each host CPU.\n"
+ "Without any domain name specified the list of\n"
+ "all running domains is printed out.\n",
+ unified_progname);
+}
+
+static void
+parse_argv(int argc, char *argv[],
+ const char **uri,
+ const char **dom_name,
+ unsigned int *milliseconds)
+{
+ int arg;
+ unsigned long val;
+ char *p;
+ struct option opt[] = {
+ {"debug", no_argument, NULL, 'd'},
+ {"help", no_argument, NULL, 'h'},
+ {"connect", required_argument, NULL, 'c'},
+ {"delay", required_argument, NULL, 'D'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while ((arg = getopt_long(argc, argv, "+:dhc:D:", opt, NULL)) != -1) {
+ switch (arg) {
+ case 'd':
+ debug = true;
+ break;
+ case 'h':
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ break;
+ case 'c':
+ *uri = optarg;
+ break;
+ case 'D':
+ /* strtoul man page suggests clearing errno prior to call */
+ errno = 0;
+ val = strtoul(optarg, &p, 10);
+ if (errno || *p || p == optarg) {
+ ERROR("Invalid number: '%s'", optarg);
+ exit(EXIT_FAILURE);
+ }
+ *milliseconds = val;
+ if (*milliseconds != val) {
+ ERROR("Integer overflow: %ld", val);
+ exit(EXIT_FAILURE);
+ }
+ break;
+ case ':':
+ ERROR("option '-%c' requires an argument", optopt);
+ exit(EXIT_FAILURE);
+ case '?':
+ if (optopt)
+ ERROR("unsupported option '-%c'. See --help.", optopt);
+ else
+ ERROR("unsupported option '%s'. See --help.", argv[optind - 1]);
+ exit(EXIT_FAILURE);
+ default:
+ ERROR("unknown option");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (argc > optind)
+ *dom_name = argv[optind];
+}
+
+static int
+fetch_domains(virConnectPtr conn)
+{
+ int num_domains, ret = -1;
+ virDomainPtr *domains = NULL;
+ ssize_t i;
+ const int list_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+
+ DEBUG("Fetching list of running domains");
+ num_domains = virConnectListAllDomains(conn, &domains, list_flags);
+
+ DEBUG("num_domains=%d", num_domains);
+ if (num_domains < 0) {
+ ERROR("Unable to fetch list of running domains");
+ goto cleanup;
+ }
+
+ printf("Running domains:\n");
+ printf("----------------\n");
+ for (i = 0; i < num_domains; i++) {
+ virDomainPtr dom = domains[i];
+ const char *dom_name = virDomainGetName(dom);
+ printf("%s\n", dom_name);
+ virDomainFree(dom);
+ }
+
+ ret = 0;
+ cleanup:
+ free(domains);
+ return ret;
+}
+
+static void
+print_cpu_usage(size_t cpu,
+ size_t ncpus,
+ unsigned long long then,
+ virTypedParameterPtr then_params,
+ size_t then_nparams,
+ unsigned long long now,
+ virTypedParameterPtr now_params,
+ size_t now_nparams)
+{
+ size_t i, j;
+ size_t nparams = now_nparams;
+ bool delim = false;
+
+ if (then_nparams != now_nparams) {
+ /* this should not happen (TM) */
+ ERROR("parameters counts don't match");
+ return;
+ }
+
+ for (i = 0; i < ncpus; i++) {
+ size_t pos = 0;
+ double usage;
+
+ /* check if the vCPU is in the maps */
+ if (now_params[i * nparams].type == 0 ||
+ then_params[i * then_nparams].type == 0)
+ continue;
+
+ for (j = 0; j < nparams; j++) {
+ pos = i * nparams + j;
+ if (STREQ(then_params[pos].field, VIR_DOMAIN_CPU_STATS_CPUTIME) ||
+ STREQ(then_params[pos].field, VIR_DOMAIN_CPU_STATS_VCPUTIME))
+ break;
+ }
+
+ if (j == nparams) {
+ ERROR("unable to find %s", VIR_DOMAIN_CPU_STATS_CPUTIME);
+ return;
+ }
+
+ DEBUG("now_params=%" PRIu64 " then_params=%" PRIu64
+ " now=%" PRIu64 " then=%" PRIu64,
+ (uint64_t)now_params[pos].value.ul,
+ (uint64_t)then_params[pos].value.ul,
+ (uint64_t)now, (uint64_t)then);
+
+ /* @now_params and @then_params are in nanoseconds, @now and @then are
+ * in microseconds. In ideal world, we would translate them both into
+ * the same scale, divide one by another and multiply by factor of 100
+ * to get percentage. However, the count of floating point operations
+ * performed has a bad effect on the precision, so instead of dividing
+ * @now_params and @then_params by 1000 and then multiplying again by
+ * 100, we divide only once by 10 and get the same result. */
+ usage = (now_params[pos].value.ul - then_params[pos].value.ul) /
+ (now - then) / 10;
+
+ if (delim)
+ printf("\t");
+ /* mingw lacks %zu */
+ printf("CPU%u: %.2lf", (unsigned)(cpu + i), usage);
+ delim = true;
+ }
+
+ printf("\n");
+}
+
+static void
+stop(int sig)
+{
+ DEBUG("Exiting on signal %d\n", sig);
+ run_top = false;
+}
+
+static int
+do_top(virConnectPtr conn,
+ const char *dom_name,
+ unsigned int milliseconds)
+{
+ int ret = -1;
+ virDomainPtr dom;
+ int max_id = 0;
+ int nparams = 0, then_nparams = 0, now_nparams = 0;
+ virTypedParameterPtr then_params = NULL, now_params = NULL;
+
+ /* Lookup the domain */
+ if (!(dom = virDomainLookupByName(conn, dom_name))) {
+ ERROR("Unable to find domain '%s'", dom_name);
+ goto cleanup;
+ }
+
+ /* and see how many vCPUs can we fetch stats for */
+ if ((max_id = virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0)) < 0) {
+ ERROR("Unable to get cpu stats");
+ goto cleanup;
+ }
+
+ /* how many stats can we get for a vCPU? */
+ if ((nparams = virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0)) < 0) {
+ ERROR("Unable to get cpu stats");
+ goto cleanup;
+ }
+
+ if (!(now_params = calloc(nparams * max_id, sizeof(*now_params))) ||
+ !(then_params = calloc(nparams * max_id, sizeof(*then_params)))) {
+ ERROR("Unable to allocate memory");
+ goto cleanup;
+ }
+
+ /* The ideal program would use sigaction to set this handler, but
+ * this way is portable to mingw. */
+ signal(SIGTERM, stop);
+ signal(SIGINT, stop);
+
+ run_top = true;
+ while (run_top) {
+ struct timeval then, now;
+
+ /* Get current time */
+ if (gettimeofday(&then, NULL) < 0) {
+ ERROR("unable to get time");
+ goto cleanup;
+ }
+
+ /* And current stats */
+ if ((then_nparams = virDomainGetCPUStats(dom, then_params,
+ nparams, 0, max_id, 0)) < 0) {
+ ERROR("Unable to get cpu stats");
+ goto cleanup;
+ }
+
+ /* Now sleep some time */
+ usleep(milliseconds * 1000); /* usleep expects microseconds */
+
+ /* And get current time */
+ if (gettimeofday(&now, NULL) < 0) {
+ ERROR("unable to get time");
+ goto cleanup;
+ }
+
+ /* And current stats */
+ if ((now_nparams = virDomainGetCPUStats(dom, now_params,
+ nparams, 0, max_id, 0)) < 0) {
+ ERROR("Unable to get cpu stats");
+ goto cleanup;
+ }
+
+ print_cpu_usage(0, max_id,
+ then.tv_sec * 1000000 + then.tv_usec,
+ then_params, then_nparams,
+ now.tv_sec * 1000000 + now.tv_usec,
+ now_params, now_nparams);
+
+ virTypedParamsClear(now_params, now_nparams * max_id);
+ virTypedParamsClear(then_params, then_nparams * max_id);
+ }
+
+ ret = 0;
+ cleanup:
+ virTypedParamsFree(now_params, nparams * max_id);
+ virTypedParamsFree(then_params, nparams * max_id);
+ if (dom)
+ virDomainFree(dom);
+ return ret;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+ virConnectPtr conn = NULL;
+ const char *uri = NULL;
+ const char *dom_name = NULL;
+ unsigned int milliseconds = 500; /* Sleep this long between two API calls */
+ const int connect_flags = 0; /* No connect flags for now */
+
+ parse_argv(argc, argv, &uri, &dom_name, &milliseconds);
+
+ DEBUG("Proceeding with uri=%s dom_name=%s milliseconds=%u",
+ uri, dom_name, milliseconds);
+
+ if (!(conn = virConnectOpenAuth(uri,
+ virConnectAuthPtrDefault,
+ connect_flags))) {
+ ERROR("Failed to connect to hypervisor");
+ goto cleanup;
+ }
+
+ DEBUG("Successfully connected");
+
+ if (!dom_name) {
+ if (fetch_domains(conn) == 0)
+ ret = EXIT_SUCCESS;
+ goto cleanup;
+ }
+
+ if (do_top(conn, dom_name, milliseconds) < 0)
+ goto cleanup;
+
+ ret = EXIT_SUCCESS;
+ cleanup:
+ if (conn) {
+ int tmp;
+ tmp = virConnectClose(conn);
+ if (tmp < 0) {
+ ERROR("Failed to disconnect from the hypervisor");
+ ret = EXIT_FAILURE;
+ } else if (tmp > 0) {
+ ERROR("One or more references were leaked after "
+ "disconnect from the hypervisor");
+ ret = EXIT_FAILURE;
+ } else {
+ DEBUG("Connection successfully closed");
+ }
+ }
+ return ret;
+}
--- /dev/null
+/**
+ * section: Informations
+ * synopsis: Extract information about Xen domain 0
+ * purpose: Demonstrate the basic use of the library to connect to the
+ * hypervisor and extract domain information.
+ * usage: info1
+ * test: info1
+ * copy: see Copyright for the status of this software.
+ */
+
+#include <stdio.h>
+#include <libvirt/libvirt.h>
+
+/**
+ * getDomainInfo:
+ * @name: the name of the domain
+ *
+ * extract the domain 0 information
+ */
+static void
+getDomainInfo(const char *uri, const char *name)
+{
+ virConnectPtr conn = NULL; /* the hypervisor connection */
+ virDomainPtr dom = NULL; /* the domain being checked */
+ virDomainInfo info; /* the information being fetched */
+ int ret;
+
+ conn = virConnectOpenReadOnly(uri);
+ if (conn == NULL) {
+ fprintf(stderr, "Failed to connect to hypervisor\n");
+ goto error;
+ }
+
+ /* Find the domain of the given name */
+ dom = virDomainLookupByName(conn, name);
+ if (dom == NULL) {
+ fprintf(stderr, "Failed to find Domain %s\n", name);
+ goto error;
+ }
+
+ /* Get the information */
+ ret = virDomainGetInfo(dom, &info);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to get information for Domain %s\n", name);
+ goto error;
+ }
+
+ printf("Domain %s: %d CPUs\n", name, info.nrVirtCpu);
+
+ error:
+ if (dom != NULL)
+ virDomainFree(dom);
+ if (conn != NULL)
+ virConnectClose(conn);
+}
+
+int main(int argc, char **argv)
+{
+ if (argc != 3) {
+ fprintf(stderr, "syntax: %s: URI NAME\n", argv[0]);
+ return 1;
+ }
+ getDomainInfo(argv[1], argv[2]);
+
+ return 0;
+}
--- /dev/null
+/*
+ * rename.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libvirt/libvirt.h>
+
+int main(int argc, char **argv)
+{
+ virConnectPtr conn = NULL; /* the hypervisor connection */
+ virDomainPtr dom = NULL; /* the domain being checked */
+ int ret = EXIT_FAILURE;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <current_domname> <temporary_domname>\n",
+ argv[0]);
+ goto error;
+ }
+
+ conn = virConnectOpen(NULL);
+ if (conn == NULL) {
+ fprintf(stderr, "Failed to connect to hypervisor\n");
+ goto error;
+ }
+
+ dom = virDomainLookupByName(conn, argv[1]);
+ if (dom == NULL) {
+ fprintf(stderr, "Failed to find domain\n");
+ goto error;
+ }
+
+ printf("Before first rename: %s\n", virDomainGetName(dom));
+
+ /* Get the information */
+ ret = virDomainRename(dom, argv[2], 0);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to rename domain\n");
+ goto error;
+ }
+
+ printf("After first rename: %s\n", virDomainGetName(dom));
+
+ /* Get the information */
+ ret = virDomainRename(dom, argv[1], 0);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to rename domain\n");
+ goto error;
+ }
+
+ printf("After second rename: %s\n", virDomainGetName(dom));
+
+ error:
+ if (dom != NULL)
+ virDomainFree(dom);
+ if (conn != NULL)
+ virConnectClose(conn);
+ return ret;
+}
--- /dev/null
+/*
+ * suspend.c: Demo program showing how to suspend a domain
+ *
+ * Copyright (C) 2006-2013 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int debug;
+
+/* On mingw, there's a header file that poisons the well:
+ *
+ *
+ * CC domtop.o
+ *domtop.c:40:0: warning: "ERROR" redefined [enabled by default]
+ * #define ERROR(...) \
+ * ^
+ *In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/windows.h:71:0,
+ * from /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:23,
+ * from ../../gnulib/lib/unistd.h:48,
+ * from domtop.c:35:
+ * /usr/i686-w64-mingw32/sys-root/mingw/include/wingdi.h:75:0: note: this is the location of the previous definition
+ * #define ERROR 0
+ */
+#undef ERROR
+#define ERROR(...) \
+do { \
+ fprintf(stderr, "ERROR %s:%d : ", __FUNCTION__, __LINE__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+} while (0)
+
+#define DEBUG(...) \
+do { \
+ if (!debug) \
+ break; \
+ fprintf(stderr, "DEBUG %s:%d : ", __FUNCTION__, __LINE__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+} while (0)
+
+static void
+print_usage(const char *progname)
+{
+ const char *unified_progname;
+
+ if (!(unified_progname = strrchr(progname, '/')))
+ unified_progname = progname;
+ else
+ unified_progname++;
+
+ printf("\n%s [options] [domain name]\n\n"
+ " options:\n"
+ " -d | --debug enable debug printings\n"
+ " -h | --help print this help\n"
+ " -c | --connect=URI hypervisor connection URI\n"
+ " -s | --seconds=X suspend domain for X seconds (default 1)\n",
+ unified_progname);
+}
+
+static int
+parse_argv(int argc, char *argv[],
+ const char **uri,
+ const char **dom_name,
+ unsigned int *seconds)
+{
+ int ret = -1;
+ int arg;
+ unsigned long val;
+ char *p;
+ struct option opt[] = {
+ {"debug", no_argument, NULL, 'd'},
+ {"help", no_argument, NULL, 'h'},
+ {"connect", required_argument, NULL, 'c'},
+ {"seconds", required_argument, NULL, 's'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while ((arg = getopt_long(argc, argv, "+:dhc:s:", opt, NULL)) != -1) {
+ switch (arg) {
+ case 'd':
+ debug = 1;
+ break;
+ case 'h':
+ print_usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ break;
+ case 'c':
+ *uri = optarg;
+ break;
+ case 's':
+ /* strtoul man page suggest clearing errno prior to call */
+ errno = 0;
+ val = strtoul(optarg, &p, 10);
+ if (errno || *p || p == optarg) {
+ ERROR("Invalid number: '%s'", optarg);
+ goto cleanup;
+ }
+ *seconds = val;
+ if (*seconds != val) {
+ ERROR("Integer overflow: %ld", val);
+ goto cleanup;
+ }
+ break;
+ case ':':
+ ERROR("option '-%c' requires an argument", optopt);
+ exit(EXIT_FAILURE);
+ case '?':
+ if (optopt)
+ ERROR("unsupported option '-%c'. See --help.", optopt);
+ else
+ ERROR("unsupported option '%s'. See --help.", argv[optind - 1]);
+ exit(EXIT_FAILURE);
+ default:
+ ERROR("unknown option");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (argc > optind)
+ *dom_name = argv[optind];
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+static int
+fetch_domains(virConnectPtr conn)
+{
+ int num_domains, ret = -1;
+ virDomainPtr *domains = NULL;
+ ssize_t i;
+ const int list_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
+
+ DEBUG("Fetching list of running domains");
+ num_domains = virConnectListAllDomains(conn, &domains, list_flags);
+
+ DEBUG("num_domains=%d", num_domains);
+ if (num_domains < 0) {
+ ERROR("Unable to fetch list of running domains");
+ goto cleanup;
+ }
+
+ printf("Running domains:\n");
+ printf("----------------\n");
+ for (i = 0; i < num_domains; i++) {
+ virDomainPtr dom = domains[i];
+ const char *dom_name = virDomainGetName(dom);
+ printf("%s\n", dom_name);
+ virDomainFree(dom);
+ }
+
+ ret = 0;
+ cleanup:
+ free(domains);
+ return ret;
+}
+
+static int
+suspend_and_resume(virConnectPtr conn,
+ const char *dom_name,
+ unsigned int seconds)
+{
+ int ret = -1;
+ virDomainPtr dom;
+ virDomainInfo dom_info;
+
+ if (!(dom = virDomainLookupByName(conn, dom_name))) {
+ ERROR("Unable to find domain '%s'", dom_name);
+ goto cleanup;
+ }
+
+ if (virDomainGetInfo(dom, &dom_info) < 0) {
+ ERROR("Unable to get domain info");
+ goto cleanup;
+ }
+
+ DEBUG("Domain state %d", dom_info.state);
+
+ switch (dom_info.state) {
+ case VIR_DOMAIN_NOSTATE:
+ case VIR_DOMAIN_RUNNING:
+ case VIR_DOMAIN_BLOCKED:
+ /* In these states the domain can be suspended */
+ DEBUG("Suspending domain");
+ if (virDomainSuspend(dom) < 0) {
+ ERROR("Unable to suspend domain");
+ goto cleanup;
+ }
+
+ DEBUG("Domain suspended. Entering sleep for %u seconds.", seconds);
+ sleep(seconds);
+ DEBUG("Sleeping done. Resuming the domain.");
+
+ if (virDomainResume(dom) < 0) {
+ ERROR("Unable to resume domain");
+ goto cleanup;
+ }
+ break;
+
+ default:
+ /* In all other states domain can't be suspended */
+ ERROR("Domain is not in a state where it can be suspended: %d",
+ dom_info.state);
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ if (dom)
+ virDomainFree(dom);
+ return ret;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ret = EXIT_FAILURE;
+ virConnectPtr conn = NULL;
+ const char *uri = NULL;
+ const char *dom_name = NULL;
+ unsigned int seconds = 1; /* Suspend domain for this long */
+ const int connect_flags = 0; /* No connect flags for now */
+
+ if (parse_argv(argc, argv, &uri, &dom_name, &seconds) < 0)
+ goto cleanup;
+
+ DEBUG("Proceeding with uri=%s dom_name=%s seconds=%u",
+ uri, dom_name, seconds);
+
+ if (!(conn = virConnectOpenAuth(uri,
+ virConnectAuthPtrDefault,
+ connect_flags))) {
+ ERROR("Failed to connect to hypervisor");
+ goto cleanup;
+ }
+
+ DEBUG("Successfully connected");
+
+ if (!dom_name) {
+ if (fetch_domains(conn) == 0)
+ ret = EXIT_SUCCESS;
+ goto cleanup;
+ }
+
+ if (suspend_and_resume(conn, dom_name, seconds) < 0)
+ goto cleanup;
+
+ ret = EXIT_SUCCESS;
+ cleanup:
+ if (conn) {
+ int tmp;
+ tmp = virConnectClose(conn);
+ if (tmp < 0) {
+ ERROR("Failed to disconnect from the hypervisor");
+ ret = EXIT_FAILURE;
+ } else if (tmp > 0) {
+ ERROR("One or more references were leaked after "
+ "disconnect from the hypervisor");
+ ret = EXIT_FAILURE;
+ } else {
+ DEBUG("Connection successfully closed");
+ }
+ }
+ return ret;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <inttypes.h>
+
+#define VIR_ENUM_SENTINELS
+
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
+#define ARRAY_CARDINALITY(Array) (sizeof(Array) / sizeof(*(Array)))
+#define STREQ(a, b) (strcmp(a, b) == 0)
+#define NULLSTR(s) ((s) ? (s) : "<null>")
+
+#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \
+ && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \
+ && !defined __cplusplus)
+# define verify(cond) _Static_assert(cond, "verify (" #cond ")")
+#else
+# define verify(cond)
+#endif
+
+#ifndef ATTRIBUTE_UNUSED
+# define ATTRIBUTE_UNUSED __attribute__((__unused__))
+#endif
+
+int run = 1;
+
+/* Callback functions */
+static void
+connectClose(virConnectPtr conn ATTRIBUTE_UNUSED,
+ int reason,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ run = 0;
+
+ switch ((virConnectCloseReason) reason) {
+ case VIR_CONNECT_CLOSE_REASON_ERROR:
+ fprintf(stderr, "Connection closed due to I/O error\n");
+ return;
+
+ case VIR_CONNECT_CLOSE_REASON_EOF:
+ fprintf(stderr, "Connection closed due to end of file\n");
+ return;
+
+ case VIR_CONNECT_CLOSE_REASON_KEEPALIVE:
+ fprintf(stderr, "Connection closed due to keepalive timeout\n");
+ return;
+
+ case VIR_CONNECT_CLOSE_REASON_CLIENT:
+ fprintf(stderr, "Connection closed due to client request\n");
+ return;
+
+ case VIR_CONNECT_CLOSE_REASON_LAST:
+ break;
+ };
+
+ fprintf(stderr, "Connection closed due to unknown reason\n");
+}
+
+
+static const char *
+eventToString(int event)
+{
+ switch ((virDomainEventType) event) {
+ case VIR_DOMAIN_EVENT_DEFINED:
+ return "Defined";
+
+ case VIR_DOMAIN_EVENT_UNDEFINED:
+ return "Undefined";
+
+ case VIR_DOMAIN_EVENT_STARTED:
+ return "Started";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED:
+ return "Suspended";
+
+ case VIR_DOMAIN_EVENT_RESUMED:
+ return "Resumed";
+
+ case VIR_DOMAIN_EVENT_STOPPED:
+ return "Stopped";
+
+ case VIR_DOMAIN_EVENT_SHUTDOWN:
+ return "Shutdown";
+
+ case VIR_DOMAIN_EVENT_PMSUSPENDED:
+ return "PMSuspended";
+
+ case VIR_DOMAIN_EVENT_CRASHED:
+ return "Crashed";
+
+ case VIR_DOMAIN_EVENT_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static const char *
+eventDetailToString(int event,
+ int detail)
+{
+ switch ((virDomainEventType) event) {
+ case VIR_DOMAIN_EVENT_DEFINED:
+ switch ((virDomainEventDefinedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_DEFINED_ADDED:
+ return "Added";
+
+ case VIR_DOMAIN_EVENT_DEFINED_UPDATED:
+ return "Updated";
+
+ case VIR_DOMAIN_EVENT_DEFINED_RENAMED:
+ return "Renamed";
+
+ case VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT:
+ return "Snapshot";
+
+ case VIR_DOMAIN_EVENT_DEFINED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_UNDEFINED:
+ switch ((virDomainEventUndefinedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_UNDEFINED_REMOVED:
+ return "Removed";
+
+ case VIR_DOMAIN_EVENT_UNDEFINED_RENAMED:
+ return "Renamed";
+
+ case VIR_DOMAIN_EVENT_UNDEFINED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_STARTED:
+ switch ((virDomainEventStartedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_STARTED_BOOTED:
+ return "Booted";
+
+ case VIR_DOMAIN_EVENT_STARTED_MIGRATED:
+ return "Migrated";
+
+ case VIR_DOMAIN_EVENT_STARTED_RESTORED:
+ return "Restored";
+
+ case VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT:
+ return "Snapshot";
+
+ case VIR_DOMAIN_EVENT_STARTED_WAKEUP:
+ return "Event wakeup";
+
+ case VIR_DOMAIN_EVENT_STARTED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_SUSPENDED:
+ switch ((virDomainEventSuspendedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_SUSPENDED_PAUSED:
+ return "Paused";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED:
+ return "Migrated";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_IOERROR:
+ return "I/O Error";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG:
+ return "Watchdog";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_RESTORED:
+ return "Restored";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT:
+ return "Snapshot";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR:
+ return "API error";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY:
+ return "Post-copy";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED:
+ return "Post-copy Error";
+
+ case VIR_DOMAIN_EVENT_SUSPENDED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_RESUMED:
+ switch ((virDomainEventResumedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_RESUMED_UNPAUSED:
+ return "Unpaused";
+
+ case VIR_DOMAIN_EVENT_RESUMED_MIGRATED:
+ return "Migrated";
+
+ case VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT:
+ return "Snapshot";
+
+ case VIR_DOMAIN_EVENT_RESUMED_POSTCOPY:
+ return "Post-copy";
+
+ case VIR_DOMAIN_EVENT_RESUMED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_STOPPED:
+ switch ((virDomainEventStoppedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN:
+ return "Shutdown";
+
+ case VIR_DOMAIN_EVENT_STOPPED_DESTROYED:
+ return "Destroyed";
+
+ case VIR_DOMAIN_EVENT_STOPPED_CRASHED:
+ return "Crashed";
+
+ case VIR_DOMAIN_EVENT_STOPPED_MIGRATED:
+ return "Migrated";
+
+ case VIR_DOMAIN_EVENT_STOPPED_SAVED:
+ return "Saved";
+
+ case VIR_DOMAIN_EVENT_STOPPED_FAILED:
+ return "Failed";
+
+ case VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT:
+ return "Snapshot";
+
+ case VIR_DOMAIN_EVENT_STOPPED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_SHUTDOWN:
+ switch ((virDomainEventShutdownDetailType) detail) {
+ case VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED:
+ return "Finished";
+
+ case VIR_DOMAIN_EVENT_SHUTDOWN_GUEST:
+ return "Guest request";
+
+ case VIR_DOMAIN_EVENT_SHUTDOWN_HOST:
+ return "Host request";
+
+ case VIR_DOMAIN_EVENT_SHUTDOWN_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_PMSUSPENDED:
+ switch ((virDomainEventPMSuspendedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY:
+ return "Memory";
+
+ case VIR_DOMAIN_EVENT_PMSUSPENDED_DISK:
+ return "Disk";
+
+ case VIR_DOMAIN_EVENT_PMSUSPENDED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_CRASHED:
+ switch ((virDomainEventCrashedDetailType) detail) {
+ case VIR_DOMAIN_EVENT_CRASHED_PANICKED:
+ return "Panicked";
+
+ case VIR_DOMAIN_EVENT_CRASHED_LAST:
+ break;
+ }
+ break;
+
+ case VIR_DOMAIN_EVENT_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static const char *
+networkEventToString(int event)
+{
+ switch ((virNetworkEventLifecycleType) event) {
+ case VIR_NETWORK_EVENT_DEFINED:
+ return "Defined";
+
+ case VIR_NETWORK_EVENT_UNDEFINED:
+ return "Undefined";
+
+ case VIR_NETWORK_EVENT_STARTED:
+ return "Started";
+
+ case VIR_NETWORK_EVENT_STOPPED:
+ return "Stopped";
+
+ case VIR_NETWORK_EVENT_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static const char *
+guestAgentLifecycleEventStateToString(int event)
+{
+ switch ((virConnectDomainEventAgentLifecycleState) event) {
+ case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED:
+ return "Disconnected";
+
+ case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED:
+ return "Connected";
+
+ case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static const char *
+guestAgentLifecycleEventReasonToString(int event)
+{
+ switch ((virConnectDomainEventAgentLifecycleReason) event) {
+ case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN:
+ return "Unknown";
+
+ case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED:
+ return "Domain started";
+
+ case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL:
+ return "Channel event";
+
+ case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+static const char *
+storagePoolEventToString(int event)
+{
+ switch ((virStoragePoolEventLifecycleType) event) {
+ case VIR_STORAGE_POOL_EVENT_DEFINED:
+ return "Defined";
+ case VIR_STORAGE_POOL_EVENT_UNDEFINED:
+ return "Undefined";
+ case VIR_STORAGE_POOL_EVENT_STARTED:
+ return "Started";
+ case VIR_STORAGE_POOL_EVENT_STOPPED:
+ return "Stopped";
+ case VIR_STORAGE_POOL_EVENT_CREATED:
+ return "Created";
+ case VIR_STORAGE_POOL_EVENT_DELETED:
+ return "Deleted";
+ case VIR_STORAGE_POOL_EVENT_LAST:
+ break;
+ }
+ return "unknown";
+}
+
+static const char *
+nodeDeviceEventToString(int event)
+{
+ switch ((virNodeDeviceEventLifecycleType) event) {
+ case VIR_NODE_DEVICE_EVENT_CREATED:
+ return "Created";
+ case VIR_NODE_DEVICE_EVENT_DELETED:
+ return "Deleted";
+ case VIR_NODE_DEVICE_EVENT_LAST:
+ break;
+ }
+ return "unknown";
+}
+
+
+static const char *
+secretEventToString(int event)
+{
+ switch ((virSecretEventLifecycleType) event) {
+ case VIR_SECRET_EVENT_DEFINED:
+ return "Defined";
+
+ case VIR_SECRET_EVENT_UNDEFINED:
+ return "Undefined";
+
+ case VIR_SECRET_EVENT_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static int
+myDomainEventCallback1(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int event,
+ int detail,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) %s %s\n", __func__, virDomainGetName(dom),
+ virDomainGetID(dom), eventToString(event),
+ eventDetailToString(event, detail));
+ return 0;
+}
+
+
+static int
+myDomainEventCallback2(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int event,
+ int detail,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) %s %s\n", __func__, virDomainGetName(dom),
+ virDomainGetID(dom), eventToString(event),
+ eventDetailToString(event, detail));
+ return 0;
+}
+
+
+static int
+myDomainEventRebootCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) rebooted\n", __func__, virDomainGetName(dom),
+ virDomainGetID(dom));
+
+ return 0;
+}
+
+
+static int
+myDomainEventRTCChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ long long offset,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) rtc change %" PRIdMAX "\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ (intmax_t)offset);
+
+ return 0;
+}
+
+
+static int
+myDomainEventBalloonChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ unsigned long long actual,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) balloon change %" PRIuMAX "KB\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), (uintmax_t)actual);
+
+ return 0;
+}
+
+
+static int
+myDomainEventWatchdogCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int action,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) watchdog action=%d\n", __func__,
+ virDomainGetName(dom), virDomainGetID(dom), action);
+
+ return 0;
+}
+
+
+static int
+myDomainEventIOErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) io error path=%s alias=%s action=%d\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ srcPath, devAlias, action);
+
+ return 0;
+}
+
+
+static int
+myDomainEventIOErrorReasonCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *srcPath,
+ const char *devAlias,
+ int action,
+ const char *reason,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) io error (reason) path=%s alias=%s "
+ "action=%d reason=%s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ srcPath, devAlias, action, reason);
+
+ return 0;
+}
+
+
+static const char *
+graphicsPhaseToStr(int phase)
+{
+ switch ((virDomainEventGraphicsPhase) phase) {
+ case VIR_DOMAIN_EVENT_GRAPHICS_CONNECT:
+ return "connected";
+
+ case VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE:
+ return "initialized";
+
+ case VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT:
+ return "disconnected";
+
+ case VIR_DOMAIN_EVENT_GRAPHICS_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static int
+myDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int phase,
+ virDomainEventGraphicsAddressPtr local,
+ virDomainEventGraphicsAddressPtr remote,
+ const char *authScheme,
+ virDomainEventGraphicsSubjectPtr subject,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ size_t i;
+ printf("%s EVENT: Domain %s(%d) graphics ", __func__, virDomainGetName(dom),
+ virDomainGetID(dom));
+
+ printf("%s ", graphicsPhaseToStr(phase));
+
+ printf("local: family=%d node=%s service=%s ",
+ local->family, local->node, local->service);
+ printf("remote: family=%d node=%s service=%s ",
+ remote->family, remote->node, remote->service);
+
+ printf("auth: %s ", authScheme);
+ for (i = 0; i < subject->nidentity; i++) {
+ printf(" identity: %s=%s",
+ subject->identities[i].type,
+ subject->identities[i].name);
+ }
+ printf("\n");
+
+ return 0;
+}
+
+
+static int
+myDomainEventControlErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) control error\n", __func__,
+ virDomainGetName(dom), virDomainGetID(dom));
+
+ return 0;
+}
+
+static const char *
+diskChangeReasonToStr(int reason)
+{
+ switch ((virConnectDomainEventDiskChangeReason) reason) {
+ case VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START:
+ return "disk empty due to startupPolicy";
+
+ case VIR_DOMAIN_EVENT_DISK_DROP_MISSING_ON_START:
+ return "disk dropped due to startupPolicy";
+
+ case VIR_DOMAIN_EVENT_DISK_CHANGE_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static int
+myDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *oldSrcPath,
+ const char *newSrcPath,
+ const char *devAlias,
+ int reason,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) disk change oldSrcPath: %s newSrcPath: %s "
+ "devAlias: %s reason: %s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ oldSrcPath, newSrcPath, devAlias, diskChangeReasonToStr(reason));
+ return 0;
+}
+
+static const char *
+trayChangeReasonToStr(int reason)
+{
+ switch ((virDomainEventTrayChangeReason) reason) {
+ case VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN:
+ return "open";
+
+ case VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE:
+ return "close";
+
+ case VIR_DOMAIN_EVENT_TRAY_CHANGE_LAST:
+ break;
+ }
+
+ return "unknown";
+};
+
+
+static int
+myDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ int reason,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) removable disk's tray change devAlias: %s "
+ "reason: %s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ devAlias, trayChangeReasonToStr(reason));
+ return 0;
+}
+
+
+static int
+myDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) system pmwakeup\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom));
+ return 0;
+}
+
+
+static int
+myDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) system pmsuspend\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom));
+ return 0;
+}
+
+
+static int
+myDomainEventPMSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int reason ATTRIBUTE_UNUSED,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) system pmsuspend-disk\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom));
+ return 0;
+}
+
+
+static int
+myDomainEventDeviceRemovedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) device removed: %s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), devAlias);
+ return 0;
+}
+
+
+static int
+myNetworkEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virNetworkPtr dom,
+ int event,
+ int detail,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Network %s %s %d\n", __func__, virNetworkGetName(dom),
+ networkEventToString(event), detail);
+ return 0;
+}
+
+static int
+myStoragePoolEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolPtr pool,
+ int event,
+ int detail,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Storage pool %s %s %d\n", __func__,
+ virStoragePoolGetName(pool),
+ storagePoolEventToString(event),
+ detail);
+ return 0;
+}
+
+
+static int
+myStoragePoolEventRefreshCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virStoragePoolPtr pool,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Storage pool %s refresh\n", __func__,
+ virStoragePoolGetName(pool));
+ return 0;
+}
+
+
+static int
+myNodeDeviceEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virNodeDevicePtr dev,
+ int event,
+ int detail,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Node device %s %s %d\n", __func__,
+ virNodeDeviceGetName(dev),
+ nodeDeviceEventToString(event),
+ detail);
+ return 0;
+}
+
+
+static int
+myNodeDeviceEventUpdateCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virNodeDevicePtr dev,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Node device %s update\n", __func__,
+ virNodeDeviceGetName(dev));
+ return 0;
+}
+
+
+static int
+mySecretEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virSecretPtr secret,
+ int event,
+ int detail,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ char uuid[VIR_UUID_STRING_BUFLEN];
+ virSecretGetUUIDString(secret, uuid);
+ printf("%s EVENT: Secret %s %s %d\n", __func__,
+ uuid,
+ secretEventToString(event),
+ detail);
+ return 0;
+}
+
+
+static int
+mySecretEventValueChanged(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virSecretPtr secret,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ char uuid[VIR_UUID_STRING_BUFLEN];
+ virSecretGetUUIDString(secret, uuid);
+ printf("%s EVENT: Secret %s\n", __func__, uuid);
+ return 0;
+}
+
+
+static void
+eventTypedParamsPrint(virTypedParameterPtr params,
+ int nparams)
+{
+ size_t i;
+
+ for (i = 0; i < nparams; i++) {
+ switch (params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ printf("\t%s: %d\n", params[i].field, params[i].value.i);
+ break;
+ case VIR_TYPED_PARAM_UINT:
+ printf("\t%s: %u\n", params[i].field, params[i].value.ui);
+ break;
+ case VIR_TYPED_PARAM_LLONG:
+ printf("\t%s: %" PRId64 "\n", params[i].field,
+ (int64_t) params[i].value.l);
+ break;
+ case VIR_TYPED_PARAM_ULLONG:
+ printf("\t%s: %" PRIu64 "\n", params[i].field,
+ (uint64_t) params[i].value.ul);
+ break;
+ case VIR_TYPED_PARAM_DOUBLE:
+ printf("\t%s: %g\n", params[i].field, params[i].value.d);
+ break;
+ case VIR_TYPED_PARAM_BOOLEAN:
+ printf("\t%s: %d\n", params[i].field, params[i].value.b);
+ break;
+ case VIR_TYPED_PARAM_STRING:
+ printf("\t%s: %s\n", params[i].field, params[i].value.s);
+ break;
+ default:
+ printf("\t%s: unknown type\n", params[i].field);
+ }
+ }
+}
+
+
+static int
+myDomainEventTunableCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ virTypedParameterPtr params,
+ int nparams,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) tunable updated:\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom));
+
+ eventTypedParamsPrint(params, nparams);
+
+ return 0;
+}
+
+
+static int
+myDomainEventAgentLifecycleCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int state,
+ int reason,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) guest agent state changed: %s reason: %s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ guestAgentLifecycleEventStateToString(state),
+ guestAgentLifecycleEventReasonToString(reason));
+
+ return 0;
+}
+
+
+static int
+myDomainEventDeviceAddedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) device added: %s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), devAlias);
+ return 0;
+}
+
+
+static const char *
+blockJobTypeToStr(int type)
+{
+ switch ((virDomainBlockJobType) type) {
+ case VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN:
+ case VIR_DOMAIN_BLOCK_JOB_TYPE_LAST:
+ break;
+
+ case VIR_DOMAIN_BLOCK_JOB_TYPE_PULL:
+ return "block pull";
+
+ case VIR_DOMAIN_BLOCK_JOB_TYPE_COPY:
+ return "block copy";
+
+ case VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT:
+ return "block commit";
+
+ case VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT:
+ return "active layer block commit";
+ }
+
+ return "unknown";
+}
+
+
+static const char *
+blockJobStatusToStr(int status)
+{
+ switch ((virConnectDomainEventBlockJobStatus) status) {
+ case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
+ return "completed";
+
+ case VIR_DOMAIN_BLOCK_JOB_FAILED:
+ return "failed";
+
+ case VIR_DOMAIN_BLOCK_JOB_CANCELED:
+ return "cancelled";
+
+ case VIR_DOMAIN_BLOCK_JOB_READY:
+ return "ready";
+
+ case VIR_DOMAIN_BLOCK_JOB_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+
+static int
+myDomainEventBlockJobCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *disk,
+ int type,
+ int status,
+ void *opaque)
+{
+ const char *eventName = opaque;
+
+ printf("%s EVENT: Domain %s(%d) block job callback '%s' disk '%s', "
+ "type '%s' status '%s'",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), eventName,
+ disk, blockJobTypeToStr(type), blockJobStatusToStr(status));
+ return 0;
+}
+
+
+static int
+myDomainEventBlockThresholdCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *dev,
+ const char *path,
+ unsigned long long threshold,
+ unsigned long long excess,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ /* Casts to uint64_t to work around mingw not knowing %lld */
+ printf("%s EVENT: Domain %s(%d) block threshold callback dev '%s'(%s), "
+ "threshold: '%" PRIu64 "', excess: '%" PRIu64 "'",
+ __func__, virDomainGetName(dom), virDomainGetID(dom),
+ dev, NULLSTR(path), (uint64_t)threshold, (uint64_t)excess);
+ return 0;
+}
+
+
+static int
+myDomainEventMigrationIterationCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int iteration,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) migration iteration '%d'\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), iteration);
+ return 0;
+}
+
+
+static int
+myDomainEventJobCompletedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ virTypedParameterPtr params,
+ int nparams,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) job completed:\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom));
+
+ eventTypedParamsPrint(params, nparams);
+
+ return 0;
+}
+
+
+static int
+myDomainEventDeviceRemovalFailedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ const char *devAlias,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ printf("%s EVENT: Domain %s(%d) device removal failed: %s\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), devAlias);
+ return 0;
+}
+
+
+static const char *
+metadataTypeToStr(int status)
+{
+ switch ((virDomainMetadataType) status) {
+ case VIR_DOMAIN_METADATA_DESCRIPTION:
+ return "description";
+
+ case VIR_DOMAIN_METADATA_TITLE:
+ return "title";
+
+ case VIR_DOMAIN_METADATA_ELEMENT:
+ return "element";
+
+ case VIR_DOMAIN_METADATA_LAST:
+ break;
+ }
+
+ return "unknown";
+}
+
+static int
+myDomainEventMetadataChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
+ virDomainPtr dom,
+ int type,
+ const char *nsuri,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ const char *typestr = metadataTypeToStr(type);
+ printf("%s EVENT: Domain %s(%d) metadata type: %s (%s)\n",
+ __func__, virDomainGetName(dom), virDomainGetID(dom), typestr, nsuri ? nsuri : "n/a");
+ return 0;
+}
+
+
+
+static void
+myFreeFunc(void *opaque)
+{
+ char *str = opaque;
+ printf("%s: Freeing [%s]\n", __func__, str);
+ free(str);
+}
+
+
+/* main test functions */
+static void
+stop(int sig)
+{
+ printf("Exiting on signal %d\n", sig);
+ run = 0;
+}
+
+
+struct domainEventData {
+ int event;
+ int id;
+ virConnectDomainEventGenericCallback cb;
+ const char *name;
+};
+
+
+#define DOMAIN_EVENT(event, callback) \
+ {event, -1, VIR_DOMAIN_EVENT_CALLBACK(callback), #event}
+
+struct domainEventData domainEvents[] = {
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback2),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_REBOOT, myDomainEventRebootCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_RTC_CHANGE, myDomainEventRTCChangeCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_WATCHDOG, myDomainEventWatchdogCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_IO_ERROR, myDomainEventIOErrorCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_GRAPHICS, myDomainEventGraphicsCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON, myDomainEventIOErrorReasonCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR, myDomainEventControlErrorCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_JOB, myDomainEventBlockJobCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DISK_CHANGE, myDomainEventDiskChangeCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, myDomainEventTrayChangeCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, myDomainEventBalloonChangeCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK, myDomainEventPMSuspendDiskCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, myDomainEventDeviceRemovedCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2, myDomainEventBlockJobCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_TUNABLE, myDomainEventTunableCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE, myDomainEventAgentLifecycleCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DEVICE_ADDED, myDomainEventDeviceAddedCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION, myDomainEventMigrationIterationCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_JOB_COMPLETED, myDomainEventJobCompletedCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED, myDomainEventDeviceRemovalFailedCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_METADATA_CHANGE, myDomainEventMetadataChangeCallback),
+ DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD, myDomainEventBlockThresholdCallback),
+};
+
+struct storagePoolEventData {
+ int event;
+ int id;
+ virConnectStoragePoolEventGenericCallback cb;
+ const char *name;
+};
+
+#define STORAGE_POOL_EVENT(event, callback) \
+ {event, -1, VIR_STORAGE_POOL_EVENT_CALLBACK(callback), #event}
+
+struct storagePoolEventData storagePoolEvents[] = {
+ STORAGE_POOL_EVENT(VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE, myStoragePoolEventCallback),
+ STORAGE_POOL_EVENT(VIR_STORAGE_POOL_EVENT_ID_REFRESH, myStoragePoolEventRefreshCallback),
+};
+
+struct nodeDeviceEventData {
+ int event;
+ int id;
+ virConnectNodeDeviceEventGenericCallback cb;
+ const char *name;
+};
+
+#define NODE_DEVICE_EVENT(event, callback) \
+ {event, -1, VIR_NODE_DEVICE_EVENT_CALLBACK(callback), #event}
+
+struct nodeDeviceEventData nodeDeviceEvents[] = {
+ NODE_DEVICE_EVENT(VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE, myNodeDeviceEventCallback),
+ NODE_DEVICE_EVENT(VIR_NODE_DEVICE_EVENT_ID_UPDATE, myNodeDeviceEventUpdateCallback),
+};
+
+struct secretEventData {
+ int event;
+ int id;
+ virConnectSecretEventGenericCallback cb;
+ const char *name;
+};
+
+#define SECRET_EVENT(event, callback) \
+ {event, -1, VIR_SECRET_EVENT_CALLBACK(callback), #event}
+
+struct secretEventData secretEvents[] = {
+ SECRET_EVENT(VIR_SECRET_EVENT_ID_LIFECYCLE, mySecretEventCallback),
+ SECRET_EVENT(VIR_SECRET_EVENT_ID_VALUE_CHANGED, mySecretEventValueChanged),
+};
+
+/* make sure that the events are kept in sync */
+verify(ARRAY_CARDINALITY(domainEvents) == VIR_DOMAIN_EVENT_ID_LAST);
+verify(ARRAY_CARDINALITY(storagePoolEvents) == VIR_STORAGE_POOL_EVENT_ID_LAST);
+verify(ARRAY_CARDINALITY(nodeDeviceEvents) == VIR_NODE_DEVICE_EVENT_ID_LAST);
+verify(ARRAY_CARDINALITY(secretEvents) == VIR_SECRET_EVENT_ID_LAST);
+
+int
+main(int argc, char **argv)
+{
+ int ret = EXIT_FAILURE;
+ virConnectPtr dconn = NULL;
+ int callback1ret = -1;
+ int callback16ret = -1;
+ size_t i;
+
+ if (argc > 1 && STREQ(argv[1], "--help")) {
+ printf("%s uri\n", argv[0]);
+ goto cleanup;
+ }
+
+ if (virInitialize() < 0) {
+ fprintf(stderr, "Failed to initialize libvirt");
+ goto cleanup;
+ }
+
+ if (virEventRegisterDefaultImpl() < 0) {
+ fprintf(stderr, "Failed to register event implementation: %s\n",
+ virGetLastErrorMessage());
+ goto cleanup;
+ }
+
+ dconn = virConnectOpenAuth(argc > 1 ? argv[1] : NULL,
+ virConnectAuthPtrDefault,
+ VIR_CONNECT_RO);
+ if (!dconn) {
+ printf("error opening\n");
+ goto cleanup;
+ }
+
+ if (virConnectRegisterCloseCallback(dconn,
+ connectClose, NULL, NULL) < 0) {
+ fprintf(stderr, "Unable to register close callback\n");
+ goto cleanup;
+ }
+
+ /* The ideal program would use sigaction to set this handler, but
+ * this way is portable to mingw. */
+ signal(SIGTERM, stop);
+ signal(SIGINT, stop);
+
+ printf("Registering event callbacks\n");
+
+ callback1ret = virConnectDomainEventRegister(dconn, myDomainEventCallback1,
+ strdup("callback 1"), myFreeFunc);
+
+ /* register common domain callbacks */
+ for (i = 0; i < ARRAY_CARDINALITY(domainEvents); i++) {
+ struct domainEventData *event = domainEvents + i;
+
+ event->id = virConnectDomainEventRegisterAny(dconn, NULL,
+ event->event,
+ event->cb,
+ strdup(event->name),
+ myFreeFunc);
+
+ if (event->id < 0) {
+ fprintf(stderr, "Failed to register event '%s'\n", event->name);
+ goto cleanup;
+ }
+ }
+
+ callback16ret = virConnectNetworkEventRegisterAny(dconn,
+ NULL,
+ VIR_NETWORK_EVENT_ID_LIFECYCLE,
+ VIR_NETWORK_EVENT_CALLBACK(myNetworkEventCallback),
+ strdup("net callback"), myFreeFunc);
+
+ /* register common storage pool callbacks */
+ for (i = 0; i < ARRAY_CARDINALITY(storagePoolEvents); i++) {
+ struct storagePoolEventData *event = storagePoolEvents + i;
+
+ event->id = virConnectStoragePoolEventRegisterAny(dconn, NULL,
+ event->event,
+ event->cb,
+ strdup(event->name),
+ myFreeFunc);
+
+ if (event->id < 0) {
+ fprintf(stderr, "Failed to register event '%s'\n", event->name);
+ goto cleanup;
+ }
+ }
+
+ /* register common node device callbacks */
+ for (i = 0; i < ARRAY_CARDINALITY(nodeDeviceEvents); i++) {
+ struct nodeDeviceEventData *event = nodeDeviceEvents + i;
+
+ event->id = virConnectNodeDeviceEventRegisterAny(dconn, NULL,
+ event->event,
+ event->cb,
+ strdup(event->name),
+ myFreeFunc);
+
+ if (event->id < 0) {
+ fprintf(stderr, "Failed to register event '%s'\n", event->name);
+ goto cleanup;
+ }
+ }
+
+ /* register common secret callbacks */
+ for (i = 0; i < ARRAY_CARDINALITY(secretEvents); i++) {
+ struct secretEventData *event = secretEvents + i;
+
+ event->id = virConnectSecretEventRegisterAny(dconn, NULL,
+ event->event,
+ event->cb,
+ strdup(event->name),
+ myFreeFunc);
+
+ if (event->id < 0) {
+ fprintf(stderr, "Failed to register event '%s'\n", event->name);
+ goto cleanup;
+ }
+ }
+
+ if ((callback1ret == -1) ||
+ (callback16ret == -1))
+ goto cleanup;
+
+ if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
+ fprintf(stderr, "Failed to start keepalive protocol: %s\n",
+ virGetLastErrorMessage());
+ run = 0;
+ }
+
+ while (run) {
+ if (virEventRunDefaultImpl() < 0) {
+ fprintf(stderr, "Failed to run event loop: %s\n",
+ virGetLastErrorMessage());
+ }
+ }
+
+ printf("Deregistering event callbacks\n");
+ virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
+ virConnectNetworkEventDeregisterAny(dconn, callback16ret);
+
+
+ printf("Deregistering domain event callbacks\n");
+ for (i = 0; i < ARRAY_CARDINALITY(domainEvents); i++) {
+ if (domainEvents[i].id > 0)
+ virConnectDomainEventDeregisterAny(dconn, domainEvents[i].id);
+ }
+
+
+ printf("Deregistering storage pool event callbacks\n");
+ for (i = 0; i < ARRAY_CARDINALITY(storagePoolEvents); i++) {
+ if (storagePoolEvents[i].id > 0)
+ virConnectStoragePoolEventDeregisterAny(dconn, storagePoolEvents[i].id);
+ }
+
+
+ printf("Deregistering node device event callbacks\n");
+ for (i = 0; i < ARRAY_CARDINALITY(nodeDeviceEvents); i++) {
+ if (nodeDeviceEvents[i].id > 0)
+ virConnectNodeDeviceEventDeregisterAny(dconn, nodeDeviceEvents[i].id);
+ }
+
+ printf("Deregistering secret event callbacks\n");
+ for (i = 0; i < ARRAY_CARDINALITY(secretEvents); i++) {
+ if (secretEvents[i].id > 0)
+ virConnectSecretEventDeregisterAny(dconn, secretEvents[i].id);
+ }
+
+
+ virConnectUnregisterCloseCallback(dconn, connectClose);
+ ret = EXIT_SUCCESS;
+
+
+ cleanup:
+ if (dconn) {
+ printf("Closing connection: ");
+ if (virConnectClose(dconn) < 0)
+ printf("failed\n");
+ printf("done\n");
+ }
+
+ return ret;
+}
--- /dev/null
+/* This file contains trivial example code to connect to the running
+ * hypervisor and gather a few bits of information about domains.
+ * Similar API's exist for storage pools, networks, and interfaces. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
+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 (!hvType) {
+ ret = 1;
+ printf("Failed to get hypervisor type: %s\n",
+ virGetLastErrorMessage());
+ goto out;
+ }
+
+ if (0 != virConnectGetVersion(conn, &hvVer)) {
+ ret = 1;
+ printf("Failed to get hypervisor version: %s\n",
+ virGetLastErrorMessage());
+ 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, numNames, numInactiveDomains, numActiveDomains;
+ ssize_t i;
+ int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE |
+ VIR_CONNECT_LIST_DOMAINS_INACTIVE;
+ virDomainPtr *nameList = NULL;
+
+ /* NB: The return from the virConnectNum*() APIs is only useful for
+ * the current call. A domain could be started or stopped and any
+ * assumptions made purely on these return values could result in
+ * unexpected results */
+ numActiveDomains = virConnectNumOfDomains(conn);
+ if (numActiveDomains == -1) {
+ ret = 1;
+ printf("Failed to get number of active domains: %s\n",
+ virGetLastErrorMessage());
+ goto out;
+ }
+
+ numInactiveDomains = virConnectNumOfDefinedDomains(conn);
+ if (numInactiveDomains == -1) {
+ ret = 1;
+ printf("Failed to get number of inactive domains: %s\n",
+ virGetLastErrorMessage());
+ goto out;
+ }
+
+ printf("There are %d active and %d inactive domains\n",
+ numActiveDomains, numInactiveDomains);
+
+ /* Return a list of all active and inactive domains. Using this API
+ * instead of virConnectListDomains() and virConnectListDefinedDomains()
+ * is preferred since it "solves" an inherit race between separated API
+ * calls if domains are started or stopped between calls */
+ numNames = virConnectListAllDomains(conn,
+ &nameList,
+ flags);
+ if (numNames == -1) {
+ ret = 1;
+ printf("Failed to get a list of all domains: %s\n",
+ virGetLastErrorMessage());
+ goto out;
+ }
+
+ for (i = 0; i < numNames; i++) {
+ int active = virDomainIsActive(nameList[i]);
+ printf(" %8s (%s)\n",
+ virDomainGetName(nameList[i]),
+ (active == 1 ? "active" : "non-active"));
+ /* must free the returned named per the API documentation */
+ virDomainFree(nameList[i]);
+ }
+ free(nameList);
+
+ out:
+ 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 (!conn) {
+ ret = 1;
+ printf("No connection to hypervisor: %s\n",
+ virGetLastErrorMessage());
+ goto out;
+ }
+
+ uri = virConnectGetURI(conn);
+ if (!uri) {
+ ret = 1;
+ printf("Failed to get URI for hypervisor connection: %s\n",
+ virGetLastErrorMessage());
+ 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: %s\n",
+ virGetLastErrorMessage());
+ ret = 1;
+ } else {
+ printf("Disconnected from hypervisor\n");
+ }
+
+ out:
+ return ret;
+}
--- /dev/null
+/* This is a copy of the hellolibvirt example demonstaring how to use
+ * virConnectOpenAuth with a custom auth callback */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
+
+static void
+showError(virConnectPtr conn)
+{
+ int ret;
+ virErrorPtr err;
+
+ err = malloc(sizeof(*err));
+ if (err == NULL) {
+ 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 (hvType == NULL) {
+ ret = 1;
+ printf("Failed to get hypervisor type\n");
+ showError(conn);
+ goto out;
+ }
+
+ if (virConnectGetVersion(conn, &hvVer) != 0) {
+ 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, numNames, numInactiveDomains, numActiveDomains;
+ ssize_t i;
+ char **nameList = NULL;
+
+ numActiveDomains = virConnectNumOfDomains(conn);
+ if (numActiveDomains == -1) {
+ ret = 1;
+ printf("Failed to get number of active domains\n");
+ showError(conn);
+ goto out;
+ }
+
+ numInactiveDomains = virConnectNumOfDefinedDomains(conn);
+ if (numInactiveDomains == -1) {
+ 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 (nameList == NULL) {
+ ret = 1;
+ printf("Could not allocate memory for list of inactive domains\n");
+ goto out;
+ }
+
+ numNames = virConnectListDefinedDomains(conn,
+ nameList,
+ numInactiveDomains);
+
+ if (numNames == -1) {
+ 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;
+}
+
+/* Struct to pass the credentials to the auth callback via the cbdata pointer */
+struct _AuthData {
+ char *username;
+ char *password;
+};
+
+typedef struct _AuthData AuthData;
+
+/* This function will be called by libvirt to obtain credentials in order to
+ * authenticate to the hypervisor */
+static int
+authCallback(virConnectCredentialPtr cred, unsigned int ncred, void *cbdata)
+{
+ size_t i;
+ AuthData *authData = cbdata;
+
+ /* libvirt might request multiple credentials in a single call.
+ * This example supports VIR_CRED_AUTHNAME and VIR_CRED_PASSPHRASE
+ * credentials only, but there are several other types.
+ *
+ * A request may also contain a prompt message that can be displayed
+ * to the user and a challenge. The challenge is specific to the
+ * credential type and hypervisor type.
+ *
+ * For example the ESX driver passes the hostname of the ESX or vCenter
+ * server as challenge. This allows a auth callback to return the
+ * proper credentials. */
+ for (i = 0; i < ncred; ++i) {
+ switch (cred[i].type) {
+ case VIR_CRED_AUTHNAME:
+ cred[i].result = strdup(authData->username);
+
+ if (cred[i].result == NULL)
+ return -1;
+
+ cred[i].resultlen = strlen(cred[i].result);
+ break;
+
+ case VIR_CRED_PASSPHRASE:
+ cred[i].result = strdup(authData->password);
+
+ if (cred[i].result == NULL)
+ return -1;
+
+ cred[i].resultlen = strlen(cred[i].result);
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+/* The list of credential types supported by our auth callback */
+static int credTypes[] = {
+ VIR_CRED_AUTHNAME,
+ VIR_CRED_PASSPHRASE
+};
+
+
+/* The auth struct that will be passed to virConnectOpenAuth */
+static virConnectAuth auth = {
+ credTypes,
+ sizeof(credTypes) / sizeof(int),
+ authCallback,
+ NULL, /* cbdata will be initialized in main */
+};
+
+
+int
+main(int argc, char *argv[])
+{
+ int ret = 0;
+ virConnectPtr conn;
+ char *uri;
+ AuthData authData;
+
+ if (argc != 4) {
+ ret = 1;
+ printf("Usage: %s <uri> <username> <password>\n", argv[0]);
+ goto out;
+ }
+
+ uri = argv[1];
+ authData.username = argv[2];
+ authData.password = argv[3];
+ auth.cbdata = &authData;
+
+ printf("Attempting to connect to hypervisor\n");
+
+ conn = virConnectOpenAuth(uri, &auth, 0);
+
+ if (NULL == conn) {
+ ret = 1;
+ printf("No connection to hypervisor\n");
+ showError(conn);
+ goto out;
+ }
+
+ uri = virConnectGetURI(conn);
+ if (uri == NULL) {
+ 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 (showHypervisorInfo(conn) != 0) {
+ ret = 1;
+ goto disconnect;
+ }
+
+ if (showDomains(conn) != 0) {
+ ret = 1;
+ goto disconnect;
+ }
+
+ disconnect:
+ if (virConnectClose(conn) != 0) {
+ printf("Failed to disconnect from hypervisor\n");
+ showError(conn);
+ ret = 1;
+ } else {
+ printf("Disconnected from hypervisor\n");
+ }
+
+ out:
+ return ret;
+}
+++ /dev/null
-/*
- * dommigrate.c: This file is largely inspired from hellolibvirt and
- * contains a trivial example that illustrate p2p domain
- * migration with libvirt.
- *
- * Copyright (C) 2014 Cloudwatt
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <libvirt/libvirt.h>
-#include <libvirt/virterror.h>
-
-
-static int
-usage(char *prgn, int ret)
-{
- printf("Usage: %s <src uri> <dst uri> <domain name>\n", prgn);
- return ret;
-}
-
-int
-main(int argc, char *argv[])
-{
- char *src_uri, *dst_uri, *domname;
- int ret = 0;
- virConnectPtr conn = NULL;
- virDomainPtr dom = NULL;
-
- if (argc < 4) {
- ret = usage(argv[0], 1);
- goto out;
- }
-
- src_uri = argv[1];
- dst_uri = argv[2];
- domname = argv[3];
-
- printf("Attempting to connect to the source hypervisor...\n");
- conn = virConnectOpenAuth(src_uri, virConnectAuthPtrDefault, 0);
- if (!conn) {
- ret = 1;
- fprintf(stderr, "No connection to the source hypervisor: %s.\n",
- virGetLastErrorMessage());
- goto out;
- }
-
- printf("Attempting to retrieve domain %s...\n", domname);
- dom = virDomainLookupByName(conn, domname);
- if (!dom) {
- fprintf(stderr, "Failed to find domain %s.\n", domname);
- goto cleanup;
- }
-
- printf("Attempting to migrate %s to %s...\n", domname, dst_uri);
- if ((ret = virDomainMigrateToURI(dom, dst_uri,
- VIR_MIGRATE_PEER2PEER,
- NULL, 0)) != 0) {
- fprintf(stderr, "Failed to migrate domain %s.\n", domname);
- goto cleanup;
- }
-
- printf("Migration finished with success.\n");
-
- cleanup:
- if (dom != NULL)
- virDomainFree(dom);
- virConnectClose(conn);
-
- out:
- return ret;
-}
+++ /dev/null
-/*
- * domtop.c: Demo program showing how to calculate CPU usage
- *
- * Copyright (C) 2014 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <getopt.h>
-#include <libvirt/libvirt.h>
-#include <libvirt/virterror.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-static bool debug;
-static bool run_top;
-
-/* On mingw, there's a header file that poisons the well:
- *
- *
- * CC domtop.o
- *domtop.c:40:0: warning: "ERROR" redefined [enabled by default]
- * #define ERROR(...) \
- * ^
- *In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/windows.h:71:0,
- * from /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:23,
- * from ../../gnulib/lib/unistd.h:48,
- * from domtop.c:35:
- * /usr/i686-w64-mingw32/sys-root/mingw/include/wingdi.h:75:0: note: this is the location of the previous definition
- * #define ERROR 0
- */
-#undef ERROR
-#define ERROR(...) \
-do { \
- fprintf(stderr, "ERROR %s:%d : ", __FUNCTION__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
-} while (0)
-
-#define DEBUG(...) \
-do { \
- if (!debug) \
- break; \
- fprintf(stderr, "DEBUG %s:%d : ", __FUNCTION__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
-} while (0)
-
-#define STREQ(a, b) (strcmp(a, b) == 0)
-
-static void
-print_usage(const char *progname)
-{
- const char *unified_progname;
-
- if (!(unified_progname = strrchr(progname, '/')))
- unified_progname = progname;
- else
- unified_progname++;
-
- printf("\n%s [options] [domain name]\n\n"
- " options:\n"
- " -d | --debug enable debug messages\n"
- " -h | --help print this help\n"
- " -c | --connect=URI hypervisor connection URI\n"
- " -D | --delay=X delay between updates in milliseconds "
- "(default is 500ms)\n"
- "\n"
- "Print the cumulative usage of each host CPU.\n"
- "Without any domain name specified the list of\n"
- "all running domains is printed out.\n",
- unified_progname);
-}
-
-static void
-parse_argv(int argc, char *argv[],
- const char **uri,
- const char **dom_name,
- unsigned int *milliseconds)
-{
- int arg;
- unsigned long val;
- char *p;
- struct option opt[] = {
- {"debug", no_argument, NULL, 'd'},
- {"help", no_argument, NULL, 'h'},
- {"connect", required_argument, NULL, 'c'},
- {"delay", required_argument, NULL, 'D'},
- {NULL, 0, NULL, 0}
- };
-
- while ((arg = getopt_long(argc, argv, "+:dhc:D:", opt, NULL)) != -1) {
- switch (arg) {
- case 'd':
- debug = true;
- break;
- case 'h':
- print_usage(argv[0]);
- exit(EXIT_SUCCESS);
- break;
- case 'c':
- *uri = optarg;
- break;
- case 'D':
- /* strtoul man page suggests clearing errno prior to call */
- errno = 0;
- val = strtoul(optarg, &p, 10);
- if (errno || *p || p == optarg) {
- ERROR("Invalid number: '%s'", optarg);
- exit(EXIT_FAILURE);
- }
- *milliseconds = val;
- if (*milliseconds != val) {
- ERROR("Integer overflow: %ld", val);
- exit(EXIT_FAILURE);
- }
- break;
- case ':':
- ERROR("option '-%c' requires an argument", optopt);
- exit(EXIT_FAILURE);
- case '?':
- if (optopt)
- ERROR("unsupported option '-%c'. See --help.", optopt);
- else
- ERROR("unsupported option '%s'. See --help.", argv[optind - 1]);
- exit(EXIT_FAILURE);
- default:
- ERROR("unknown option");
- exit(EXIT_FAILURE);
- }
- }
-
- if (argc > optind)
- *dom_name = argv[optind];
-}
-
-static int
-fetch_domains(virConnectPtr conn)
-{
- int num_domains, ret = -1;
- virDomainPtr *domains = NULL;
- ssize_t i;
- const int list_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
-
- DEBUG("Fetching list of running domains");
- num_domains = virConnectListAllDomains(conn, &domains, list_flags);
-
- DEBUG("num_domains=%d", num_domains);
- if (num_domains < 0) {
- ERROR("Unable to fetch list of running domains");
- goto cleanup;
- }
-
- printf("Running domains:\n");
- printf("----------------\n");
- for (i = 0; i < num_domains; i++) {
- virDomainPtr dom = domains[i];
- const char *dom_name = virDomainGetName(dom);
- printf("%s\n", dom_name);
- virDomainFree(dom);
- }
-
- ret = 0;
- cleanup:
- free(domains);
- return ret;
-}
-
-static void
-print_cpu_usage(size_t cpu,
- size_t ncpus,
- unsigned long long then,
- virTypedParameterPtr then_params,
- size_t then_nparams,
- unsigned long long now,
- virTypedParameterPtr now_params,
- size_t now_nparams)
-{
- size_t i, j;
- size_t nparams = now_nparams;
- bool delim = false;
-
- if (then_nparams != now_nparams) {
- /* this should not happen (TM) */
- ERROR("parameters counts don't match");
- return;
- }
-
- for (i = 0; i < ncpus; i++) {
- size_t pos = 0;
- double usage;
-
- /* check if the vCPU is in the maps */
- if (now_params[i * nparams].type == 0 ||
- then_params[i * then_nparams].type == 0)
- continue;
-
- for (j = 0; j < nparams; j++) {
- pos = i * nparams + j;
- if (STREQ(then_params[pos].field, VIR_DOMAIN_CPU_STATS_CPUTIME) ||
- STREQ(then_params[pos].field, VIR_DOMAIN_CPU_STATS_VCPUTIME))
- break;
- }
-
- if (j == nparams) {
- ERROR("unable to find %s", VIR_DOMAIN_CPU_STATS_CPUTIME);
- return;
- }
-
- DEBUG("now_params=%" PRIu64 " then_params=%" PRIu64
- " now=%" PRIu64 " then=%" PRIu64,
- (uint64_t)now_params[pos].value.ul,
- (uint64_t)then_params[pos].value.ul,
- (uint64_t)now, (uint64_t)then);
-
- /* @now_params and @then_params are in nanoseconds, @now and @then are
- * in microseconds. In ideal world, we would translate them both into
- * the same scale, divide one by another and multiply by factor of 100
- * to get percentage. However, the count of floating point operations
- * performed has a bad effect on the precision, so instead of dividing
- * @now_params and @then_params by 1000 and then multiplying again by
- * 100, we divide only once by 10 and get the same result. */
- usage = (now_params[pos].value.ul - then_params[pos].value.ul) /
- (now - then) / 10;
-
- if (delim)
- printf("\t");
- /* mingw lacks %zu */
- printf("CPU%u: %.2lf", (unsigned)(cpu + i), usage);
- delim = true;
- }
-
- printf("\n");
-}
-
-static void
-stop(int sig)
-{
- DEBUG("Exiting on signal %d\n", sig);
- run_top = false;
-}
-
-static int
-do_top(virConnectPtr conn,
- const char *dom_name,
- unsigned int milliseconds)
-{
- int ret = -1;
- virDomainPtr dom;
- int max_id = 0;
- int nparams = 0, then_nparams = 0, now_nparams = 0;
- virTypedParameterPtr then_params = NULL, now_params = NULL;
-
- /* Lookup the domain */
- if (!(dom = virDomainLookupByName(conn, dom_name))) {
- ERROR("Unable to find domain '%s'", dom_name);
- goto cleanup;
- }
-
- /* and see how many vCPUs can we fetch stats for */
- if ((max_id = virDomainGetCPUStats(dom, NULL, 0, 0, 0, 0)) < 0) {
- ERROR("Unable to get cpu stats");
- goto cleanup;
- }
-
- /* how many stats can we get for a vCPU? */
- if ((nparams = virDomainGetCPUStats(dom, NULL, 0, 0, 1, 0)) < 0) {
- ERROR("Unable to get cpu stats");
- goto cleanup;
- }
-
- if (!(now_params = calloc(nparams * max_id, sizeof(*now_params))) ||
- !(then_params = calloc(nparams * max_id, sizeof(*then_params)))) {
- ERROR("Unable to allocate memory");
- goto cleanup;
- }
-
- /* The ideal program would use sigaction to set this handler, but
- * this way is portable to mingw. */
- signal(SIGTERM, stop);
- signal(SIGINT, stop);
-
- run_top = true;
- while (run_top) {
- struct timeval then, now;
-
- /* Get current time */
- if (gettimeofday(&then, NULL) < 0) {
- ERROR("unable to get time");
- goto cleanup;
- }
-
- /* And current stats */
- if ((then_nparams = virDomainGetCPUStats(dom, then_params,
- nparams, 0, max_id, 0)) < 0) {
- ERROR("Unable to get cpu stats");
- goto cleanup;
- }
-
- /* Now sleep some time */
- usleep(milliseconds * 1000); /* usleep expects microseconds */
-
- /* And get current time */
- if (gettimeofday(&now, NULL) < 0) {
- ERROR("unable to get time");
- goto cleanup;
- }
-
- /* And current stats */
- if ((now_nparams = virDomainGetCPUStats(dom, now_params,
- nparams, 0, max_id, 0)) < 0) {
- ERROR("Unable to get cpu stats");
- goto cleanup;
- }
-
- print_cpu_usage(0, max_id,
- then.tv_sec * 1000000 + then.tv_usec,
- then_params, then_nparams,
- now.tv_sec * 1000000 + now.tv_usec,
- now_params, now_nparams);
-
- virTypedParamsClear(now_params, now_nparams * max_id);
- virTypedParamsClear(then_params, then_nparams * max_id);
- }
-
- ret = 0;
- cleanup:
- virTypedParamsFree(now_params, nparams * max_id);
- virTypedParamsFree(then_params, nparams * max_id);
- if (dom)
- virDomainFree(dom);
- return ret;
-}
-
-int
-main(int argc, char *argv[])
-{
- int ret = EXIT_FAILURE;
- virConnectPtr conn = NULL;
- const char *uri = NULL;
- const char *dom_name = NULL;
- unsigned int milliseconds = 500; /* Sleep this long between two API calls */
- const int connect_flags = 0; /* No connect flags for now */
-
- parse_argv(argc, argv, &uri, &dom_name, &milliseconds);
-
- DEBUG("Proceeding with uri=%s dom_name=%s milliseconds=%u",
- uri, dom_name, milliseconds);
-
- if (!(conn = virConnectOpenAuth(uri,
- virConnectAuthPtrDefault,
- connect_flags))) {
- ERROR("Failed to connect to hypervisor");
- goto cleanup;
- }
-
- DEBUG("Successfully connected");
-
- if (!dom_name) {
- if (fetch_domains(conn) == 0)
- ret = EXIT_SUCCESS;
- goto cleanup;
- }
-
- if (do_top(conn, dom_name, milliseconds) < 0)
- goto cleanup;
-
- ret = EXIT_SUCCESS;
- cleanup:
- if (conn) {
- int tmp;
- tmp = virConnectClose(conn);
- if (tmp < 0) {
- ERROR("Failed to disconnect from the hypervisor");
- ret = EXIT_FAILURE;
- } else if (tmp > 0) {
- ERROR("One or more references were leaked after "
- "disconnect from the hypervisor");
- ret = EXIT_FAILURE;
- } else {
- DEBUG("Connection successfully closed");
- }
- }
- return ret;
-}
+++ /dev/null
-/**
- * section: Informations
- * synopsis: Extract information about Xen domain 0
- * purpose: Demonstrate the basic use of the library to connect to the
- * hypervisor and extract domain information.
- * usage: info1
- * test: info1
- * copy: see Copyright for the status of this software.
- */
-
-#include <stdio.h>
-#include <libvirt/libvirt.h>
-
-/**
- * getDomainInfo:
- * @name: the name of the domain
- *
- * extract the domain 0 information
- */
-static void
-getDomainInfo(const char *uri, const char *name)
-{
- virConnectPtr conn = NULL; /* the hypervisor connection */
- virDomainPtr dom = NULL; /* the domain being checked */
- virDomainInfo info; /* the information being fetched */
- int ret;
-
- conn = virConnectOpenReadOnly(uri);
- if (conn == NULL) {
- fprintf(stderr, "Failed to connect to hypervisor\n");
- goto error;
- }
-
- /* Find the domain of the given name */
- dom = virDomainLookupByName(conn, name);
- if (dom == NULL) {
- fprintf(stderr, "Failed to find Domain %s\n", name);
- goto error;
- }
-
- /* Get the information */
- ret = virDomainGetInfo(dom, &info);
- if (ret < 0) {
- fprintf(stderr, "Failed to get information for Domain %s\n", name);
- goto error;
- }
-
- printf("Domain %s: %d CPUs\n", name, info.nrVirtCpu);
-
- error:
- if (dom != NULL)
- virDomainFree(dom);
- if (conn != NULL)
- virConnectClose(conn);
-}
-
-int main(int argc, char **argv)
-{
- if (argc != 3) {
- fprintf(stderr, "syntax: %s: URI NAME\n", argv[0]);
- return 1;
- }
- getDomainInfo(argv[1], argv[2]);
-
- return 0;
-}
+++ /dev/null
-/*
- * rename.c
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <libvirt/libvirt.h>
-
-int main(int argc, char **argv)
-{
- virConnectPtr conn = NULL; /* the hypervisor connection */
- virDomainPtr dom = NULL; /* the domain being checked */
- int ret = EXIT_FAILURE;
-
- if (argc != 3) {
- fprintf(stderr, "Usage: %s <current_domname> <temporary_domname>\n",
- argv[0]);
- goto error;
- }
-
- conn = virConnectOpen(NULL);
- if (conn == NULL) {
- fprintf(stderr, "Failed to connect to hypervisor\n");
- goto error;
- }
-
- dom = virDomainLookupByName(conn, argv[1]);
- if (dom == NULL) {
- fprintf(stderr, "Failed to find domain\n");
- goto error;
- }
-
- printf("Before first rename: %s\n", virDomainGetName(dom));
-
- /* Get the information */
- ret = virDomainRename(dom, argv[2], 0);
- if (ret < 0) {
- fprintf(stderr, "Failed to rename domain\n");
- goto error;
- }
-
- printf("After first rename: %s\n", virDomainGetName(dom));
-
- /* Get the information */
- ret = virDomainRename(dom, argv[1], 0);
- if (ret < 0) {
- fprintf(stderr, "Failed to rename domain\n");
- goto error;
- }
-
- printf("After second rename: %s\n", virDomainGetName(dom));
-
- error:
- if (dom != NULL)
- virDomainFree(dom);
- if (conn != NULL)
- virConnectClose(conn);
- return ret;
-}
+++ /dev/null
-/*
- * suspend.c: Demo program showing how to suspend a domain
- *
- * Copyright (C) 2006-2013 Red Hat, Inc.
- * Copyright (C) 2006 Daniel P. Berrange
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <getopt.h>
-#include <libvirt/libvirt.h>
-#include <libvirt/virterror.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-static int debug;
-
-/* On mingw, there's a header file that poisons the well:
- *
- *
- * CC domtop.o
- *domtop.c:40:0: warning: "ERROR" redefined [enabled by default]
- * #define ERROR(...) \
- * ^
- *In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/windows.h:71:0,
- * from /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:23,
- * from ../../gnulib/lib/unistd.h:48,
- * from domtop.c:35:
- * /usr/i686-w64-mingw32/sys-root/mingw/include/wingdi.h:75:0: note: this is the location of the previous definition
- * #define ERROR 0
- */
-#undef ERROR
-#define ERROR(...) \
-do { \
- fprintf(stderr, "ERROR %s:%d : ", __FUNCTION__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
-} while (0)
-
-#define DEBUG(...) \
-do { \
- if (!debug) \
- break; \
- fprintf(stderr, "DEBUG %s:%d : ", __FUNCTION__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
-} while (0)
-
-static void
-print_usage(const char *progname)
-{
- const char *unified_progname;
-
- if (!(unified_progname = strrchr(progname, '/')))
- unified_progname = progname;
- else
- unified_progname++;
-
- printf("\n%s [options] [domain name]\n\n"
- " options:\n"
- " -d | --debug enable debug printings\n"
- " -h | --help print this help\n"
- " -c | --connect=URI hypervisor connection URI\n"
- " -s | --seconds=X suspend domain for X seconds (default 1)\n",
- unified_progname);
-}
-
-static int
-parse_argv(int argc, char *argv[],
- const char **uri,
- const char **dom_name,
- unsigned int *seconds)
-{
- int ret = -1;
- int arg;
- unsigned long val;
- char *p;
- struct option opt[] = {
- {"debug", no_argument, NULL, 'd'},
- {"help", no_argument, NULL, 'h'},
- {"connect", required_argument, NULL, 'c'},
- {"seconds", required_argument, NULL, 's'},
- {NULL, 0, NULL, 0}
- };
-
- while ((arg = getopt_long(argc, argv, "+:dhc:s:", opt, NULL)) != -1) {
- switch (arg) {
- case 'd':
- debug = 1;
- break;
- case 'h':
- print_usage(argv[0]);
- exit(EXIT_SUCCESS);
- break;
- case 'c':
- *uri = optarg;
- break;
- case 's':
- /* strtoul man page suggest clearing errno prior to call */
- errno = 0;
- val = strtoul(optarg, &p, 10);
- if (errno || *p || p == optarg) {
- ERROR("Invalid number: '%s'", optarg);
- goto cleanup;
- }
- *seconds = val;
- if (*seconds != val) {
- ERROR("Integer overflow: %ld", val);
- goto cleanup;
- }
- break;
- case ':':
- ERROR("option '-%c' requires an argument", optopt);
- exit(EXIT_FAILURE);
- case '?':
- if (optopt)
- ERROR("unsupported option '-%c'. See --help.", optopt);
- else
- ERROR("unsupported option '%s'. See --help.", argv[optind - 1]);
- exit(EXIT_FAILURE);
- default:
- ERROR("unknown option");
- exit(EXIT_FAILURE);
- }
- }
-
- if (argc > optind)
- *dom_name = argv[optind];
-
- ret = 0;
- cleanup:
- return ret;
-}
-
-static int
-fetch_domains(virConnectPtr conn)
-{
- int num_domains, ret = -1;
- virDomainPtr *domains = NULL;
- ssize_t i;
- const int list_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
-
- DEBUG("Fetching list of running domains");
- num_domains = virConnectListAllDomains(conn, &domains, list_flags);
-
- DEBUG("num_domains=%d", num_domains);
- if (num_domains < 0) {
- ERROR("Unable to fetch list of running domains");
- goto cleanup;
- }
-
- printf("Running domains:\n");
- printf("----------------\n");
- for (i = 0; i < num_domains; i++) {
- virDomainPtr dom = domains[i];
- const char *dom_name = virDomainGetName(dom);
- printf("%s\n", dom_name);
- virDomainFree(dom);
- }
-
- ret = 0;
- cleanup:
- free(domains);
- return ret;
-}
-
-static int
-suspend_and_resume(virConnectPtr conn,
- const char *dom_name,
- unsigned int seconds)
-{
- int ret = -1;
- virDomainPtr dom;
- virDomainInfo dom_info;
-
- if (!(dom = virDomainLookupByName(conn, dom_name))) {
- ERROR("Unable to find domain '%s'", dom_name);
- goto cleanup;
- }
-
- if (virDomainGetInfo(dom, &dom_info) < 0) {
- ERROR("Unable to get domain info");
- goto cleanup;
- }
-
- DEBUG("Domain state %d", dom_info.state);
-
- switch (dom_info.state) {
- case VIR_DOMAIN_NOSTATE:
- case VIR_DOMAIN_RUNNING:
- case VIR_DOMAIN_BLOCKED:
- /* In these states the domain can be suspended */
- DEBUG("Suspending domain");
- if (virDomainSuspend(dom) < 0) {
- ERROR("Unable to suspend domain");
- goto cleanup;
- }
-
- DEBUG("Domain suspended. Entering sleep for %u seconds.", seconds);
- sleep(seconds);
- DEBUG("Sleeping done. Resuming the domain.");
-
- if (virDomainResume(dom) < 0) {
- ERROR("Unable to resume domain");
- goto cleanup;
- }
- break;
-
- default:
- /* In all other states domain can't be suspended */
- ERROR("Domain is not in a state where it can be suspended: %d",
- dom_info.state);
- goto cleanup;
- }
-
- ret = 0;
- cleanup:
- if (dom)
- virDomainFree(dom);
- return ret;
-}
-
-int
-main(int argc, char *argv[])
-{
- int ret = EXIT_FAILURE;
- virConnectPtr conn = NULL;
- const char *uri = NULL;
- const char *dom_name = NULL;
- unsigned int seconds = 1; /* Suspend domain for this long */
- const int connect_flags = 0; /* No connect flags for now */
-
- if (parse_argv(argc, argv, &uri, &dom_name, &seconds) < 0)
- goto cleanup;
-
- DEBUG("Proceeding with uri=%s dom_name=%s seconds=%u",
- uri, dom_name, seconds);
-
- if (!(conn = virConnectOpenAuth(uri,
- virConnectAuthPtrDefault,
- connect_flags))) {
- ERROR("Failed to connect to hypervisor");
- goto cleanup;
- }
-
- DEBUG("Successfully connected");
-
- if (!dom_name) {
- if (fetch_domains(conn) == 0)
- ret = EXIT_SUCCESS;
- goto cleanup;
- }
-
- if (suspend_and_resume(conn, dom_name, seconds) < 0)
- goto cleanup;
-
- ret = EXIT_SUCCESS;
- cleanup:
- if (conn) {
- int tmp;
- tmp = virConnectClose(conn);
- if (tmp < 0) {
- ERROR("Failed to disconnect from the hypervisor");
- ret = EXIT_FAILURE;
- } else if (tmp > 0) {
- ERROR("One or more references were leaked after "
- "disconnect from the hypervisor");
- ret = EXIT_FAILURE;
- } else {
- DEBUG("Connection successfully closed");
- }
- }
- return ret;
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <inttypes.h>
-
-#define VIR_ENUM_SENTINELS
-
-#include <libvirt/libvirt.h>
-#include <libvirt/virterror.h>
-
-#define ARRAY_CARDINALITY(Array) (sizeof(Array) / sizeof(*(Array)))
-#define STREQ(a, b) (strcmp(a, b) == 0)
-#define NULLSTR(s) ((s) ? (s) : "<null>")
-
-#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \
- && (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \
- && !defined __cplusplus)
-# define verify(cond) _Static_assert(cond, "verify (" #cond ")")
-#else
-# define verify(cond)
-#endif
-
-#ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__((__unused__))
-#endif
-
-int run = 1;
-
-/* Callback functions */
-static void
-connectClose(virConnectPtr conn ATTRIBUTE_UNUSED,
- int reason,
- void *opaque ATTRIBUTE_UNUSED)
-{
- run = 0;
-
- switch ((virConnectCloseReason) reason) {
- case VIR_CONNECT_CLOSE_REASON_ERROR:
- fprintf(stderr, "Connection closed due to I/O error\n");
- return;
-
- case VIR_CONNECT_CLOSE_REASON_EOF:
- fprintf(stderr, "Connection closed due to end of file\n");
- return;
-
- case VIR_CONNECT_CLOSE_REASON_KEEPALIVE:
- fprintf(stderr, "Connection closed due to keepalive timeout\n");
- return;
-
- case VIR_CONNECT_CLOSE_REASON_CLIENT:
- fprintf(stderr, "Connection closed due to client request\n");
- return;
-
- case VIR_CONNECT_CLOSE_REASON_LAST:
- break;
- };
-
- fprintf(stderr, "Connection closed due to unknown reason\n");
-}
-
-
-static const char *
-eventToString(int event)
-{
- switch ((virDomainEventType) event) {
- case VIR_DOMAIN_EVENT_DEFINED:
- return "Defined";
-
- case VIR_DOMAIN_EVENT_UNDEFINED:
- return "Undefined";
-
- case VIR_DOMAIN_EVENT_STARTED:
- return "Started";
-
- case VIR_DOMAIN_EVENT_SUSPENDED:
- return "Suspended";
-
- case VIR_DOMAIN_EVENT_RESUMED:
- return "Resumed";
-
- case VIR_DOMAIN_EVENT_STOPPED:
- return "Stopped";
-
- case VIR_DOMAIN_EVENT_SHUTDOWN:
- return "Shutdown";
-
- case VIR_DOMAIN_EVENT_PMSUSPENDED:
- return "PMSuspended";
-
- case VIR_DOMAIN_EVENT_CRASHED:
- return "Crashed";
-
- case VIR_DOMAIN_EVENT_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static const char *
-eventDetailToString(int event,
- int detail)
-{
- switch ((virDomainEventType) event) {
- case VIR_DOMAIN_EVENT_DEFINED:
- switch ((virDomainEventDefinedDetailType) detail) {
- case VIR_DOMAIN_EVENT_DEFINED_ADDED:
- return "Added";
-
- case VIR_DOMAIN_EVENT_DEFINED_UPDATED:
- return "Updated";
-
- case VIR_DOMAIN_EVENT_DEFINED_RENAMED:
- return "Renamed";
-
- case VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT:
- return "Snapshot";
-
- case VIR_DOMAIN_EVENT_DEFINED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_UNDEFINED:
- switch ((virDomainEventUndefinedDetailType) detail) {
- case VIR_DOMAIN_EVENT_UNDEFINED_REMOVED:
- return "Removed";
-
- case VIR_DOMAIN_EVENT_UNDEFINED_RENAMED:
- return "Renamed";
-
- case VIR_DOMAIN_EVENT_UNDEFINED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_STARTED:
- switch ((virDomainEventStartedDetailType) detail) {
- case VIR_DOMAIN_EVENT_STARTED_BOOTED:
- return "Booted";
-
- case VIR_DOMAIN_EVENT_STARTED_MIGRATED:
- return "Migrated";
-
- case VIR_DOMAIN_EVENT_STARTED_RESTORED:
- return "Restored";
-
- case VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT:
- return "Snapshot";
-
- case VIR_DOMAIN_EVENT_STARTED_WAKEUP:
- return "Event wakeup";
-
- case VIR_DOMAIN_EVENT_STARTED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_SUSPENDED:
- switch ((virDomainEventSuspendedDetailType) detail) {
- case VIR_DOMAIN_EVENT_SUSPENDED_PAUSED:
- return "Paused";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED:
- return "Migrated";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_IOERROR:
- return "I/O Error";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG:
- return "Watchdog";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_RESTORED:
- return "Restored";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT:
- return "Snapshot";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR:
- return "API error";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY:
- return "Post-copy";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED:
- return "Post-copy Error";
-
- case VIR_DOMAIN_EVENT_SUSPENDED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_RESUMED:
- switch ((virDomainEventResumedDetailType) detail) {
- case VIR_DOMAIN_EVENT_RESUMED_UNPAUSED:
- return "Unpaused";
-
- case VIR_DOMAIN_EVENT_RESUMED_MIGRATED:
- return "Migrated";
-
- case VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT:
- return "Snapshot";
-
- case VIR_DOMAIN_EVENT_RESUMED_POSTCOPY:
- return "Post-copy";
-
- case VIR_DOMAIN_EVENT_RESUMED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_STOPPED:
- switch ((virDomainEventStoppedDetailType) detail) {
- case VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN:
- return "Shutdown";
-
- case VIR_DOMAIN_EVENT_STOPPED_DESTROYED:
- return "Destroyed";
-
- case VIR_DOMAIN_EVENT_STOPPED_CRASHED:
- return "Crashed";
-
- case VIR_DOMAIN_EVENT_STOPPED_MIGRATED:
- return "Migrated";
-
- case VIR_DOMAIN_EVENT_STOPPED_SAVED:
- return "Saved";
-
- case VIR_DOMAIN_EVENT_STOPPED_FAILED:
- return "Failed";
-
- case VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT:
- return "Snapshot";
-
- case VIR_DOMAIN_EVENT_STOPPED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_SHUTDOWN:
- switch ((virDomainEventShutdownDetailType) detail) {
- case VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED:
- return "Finished";
-
- case VIR_DOMAIN_EVENT_SHUTDOWN_GUEST:
- return "Guest request";
-
- case VIR_DOMAIN_EVENT_SHUTDOWN_HOST:
- return "Host request";
-
- case VIR_DOMAIN_EVENT_SHUTDOWN_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_PMSUSPENDED:
- switch ((virDomainEventPMSuspendedDetailType) detail) {
- case VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY:
- return "Memory";
-
- case VIR_DOMAIN_EVENT_PMSUSPENDED_DISK:
- return "Disk";
-
- case VIR_DOMAIN_EVENT_PMSUSPENDED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_CRASHED:
- switch ((virDomainEventCrashedDetailType) detail) {
- case VIR_DOMAIN_EVENT_CRASHED_PANICKED:
- return "Panicked";
-
- case VIR_DOMAIN_EVENT_CRASHED_LAST:
- break;
- }
- break;
-
- case VIR_DOMAIN_EVENT_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static const char *
-networkEventToString(int event)
-{
- switch ((virNetworkEventLifecycleType) event) {
- case VIR_NETWORK_EVENT_DEFINED:
- return "Defined";
-
- case VIR_NETWORK_EVENT_UNDEFINED:
- return "Undefined";
-
- case VIR_NETWORK_EVENT_STARTED:
- return "Started";
-
- case VIR_NETWORK_EVENT_STOPPED:
- return "Stopped";
-
- case VIR_NETWORK_EVENT_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static const char *
-guestAgentLifecycleEventStateToString(int event)
-{
- switch ((virConnectDomainEventAgentLifecycleState) event) {
- case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED:
- return "Disconnected";
-
- case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED:
- return "Connected";
-
- case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static const char *
-guestAgentLifecycleEventReasonToString(int event)
-{
- switch ((virConnectDomainEventAgentLifecycleReason) event) {
- case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN:
- return "Unknown";
-
- case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED:
- return "Domain started";
-
- case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL:
- return "Channel event";
-
- case VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_LAST:
- break;
- }
-
- return "unknown";
-}
-
-static const char *
-storagePoolEventToString(int event)
-{
- switch ((virStoragePoolEventLifecycleType) event) {
- case VIR_STORAGE_POOL_EVENT_DEFINED:
- return "Defined";
- case VIR_STORAGE_POOL_EVENT_UNDEFINED:
- return "Undefined";
- case VIR_STORAGE_POOL_EVENT_STARTED:
- return "Started";
- case VIR_STORAGE_POOL_EVENT_STOPPED:
- return "Stopped";
- case VIR_STORAGE_POOL_EVENT_CREATED:
- return "Created";
- case VIR_STORAGE_POOL_EVENT_DELETED:
- return "Deleted";
- case VIR_STORAGE_POOL_EVENT_LAST:
- break;
- }
- return "unknown";
-}
-
-static const char *
-nodeDeviceEventToString(int event)
-{
- switch ((virNodeDeviceEventLifecycleType) event) {
- case VIR_NODE_DEVICE_EVENT_CREATED:
- return "Created";
- case VIR_NODE_DEVICE_EVENT_DELETED:
- return "Deleted";
- case VIR_NODE_DEVICE_EVENT_LAST:
- break;
- }
- return "unknown";
-}
-
-
-static const char *
-secretEventToString(int event)
-{
- switch ((virSecretEventLifecycleType) event) {
- case VIR_SECRET_EVENT_DEFINED:
- return "Defined";
-
- case VIR_SECRET_EVENT_UNDEFINED:
- return "Undefined";
-
- case VIR_SECRET_EVENT_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static int
-myDomainEventCallback1(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int event,
- int detail,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) %s %s\n", __func__, virDomainGetName(dom),
- virDomainGetID(dom), eventToString(event),
- eventDetailToString(event, detail));
- return 0;
-}
-
-
-static int
-myDomainEventCallback2(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int event,
- int detail,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) %s %s\n", __func__, virDomainGetName(dom),
- virDomainGetID(dom), eventToString(event),
- eventDetailToString(event, detail));
- return 0;
-}
-
-
-static int
-myDomainEventRebootCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) rebooted\n", __func__, virDomainGetName(dom),
- virDomainGetID(dom));
-
- return 0;
-}
-
-
-static int
-myDomainEventRTCChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- long long offset,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) rtc change %" PRIdMAX "\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom),
- (intmax_t)offset);
-
- return 0;
-}
-
-
-static int
-myDomainEventBalloonChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- unsigned long long actual,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) balloon change %" PRIuMAX "KB\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom), (uintmax_t)actual);
-
- return 0;
-}
-
-
-static int
-myDomainEventWatchdogCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int action,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) watchdog action=%d\n", __func__,
- virDomainGetName(dom), virDomainGetID(dom), action);
-
- return 0;
-}
-
-
-static int
-myDomainEventIOErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *srcPath,
- const char *devAlias,
- int action,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) io error path=%s alias=%s action=%d\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom),
- srcPath, devAlias, action);
-
- return 0;
-}
-
-
-static int
-myDomainEventIOErrorReasonCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *srcPath,
- const char *devAlias,
- int action,
- const char *reason,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) io error (reason) path=%s alias=%s "
- "action=%d reason=%s\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom),
- srcPath, devAlias, action, reason);
-
- return 0;
-}
-
-
-static const char *
-graphicsPhaseToStr(int phase)
-{
- switch ((virDomainEventGraphicsPhase) phase) {
- case VIR_DOMAIN_EVENT_GRAPHICS_CONNECT:
- return "connected";
-
- case VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE:
- return "initialized";
-
- case VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT:
- return "disconnected";
-
- case VIR_DOMAIN_EVENT_GRAPHICS_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static int
-myDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int phase,
- virDomainEventGraphicsAddressPtr local,
- virDomainEventGraphicsAddressPtr remote,
- const char *authScheme,
- virDomainEventGraphicsSubjectPtr subject,
- void *opaque ATTRIBUTE_UNUSED)
-{
- size_t i;
- printf("%s EVENT: Domain %s(%d) graphics ", __func__, virDomainGetName(dom),
- virDomainGetID(dom));
-
- printf("%s ", graphicsPhaseToStr(phase));
-
- printf("local: family=%d node=%s service=%s ",
- local->family, local->node, local->service);
- printf("remote: family=%d node=%s service=%s ",
- remote->family, remote->node, remote->service);
-
- printf("auth: %s ", authScheme);
- for (i = 0; i < subject->nidentity; i++) {
- printf(" identity: %s=%s",
- subject->identities[i].type,
- subject->identities[i].name);
- }
- printf("\n");
-
- return 0;
-}
-
-
-static int
-myDomainEventControlErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) control error\n", __func__,
- virDomainGetName(dom), virDomainGetID(dom));
-
- return 0;
-}
-
-static const char *
-diskChangeReasonToStr(int reason)
-{
- switch ((virConnectDomainEventDiskChangeReason) reason) {
- case VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START:
- return "disk empty due to startupPolicy";
-
- case VIR_DOMAIN_EVENT_DISK_DROP_MISSING_ON_START:
- return "disk dropped due to startupPolicy";
-
- case VIR_DOMAIN_EVENT_DISK_CHANGE_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static int
-myDomainEventDiskChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *oldSrcPath,
- const char *newSrcPath,
- const char *devAlias,
- int reason,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) disk change oldSrcPath: %s newSrcPath: %s "
- "devAlias: %s reason: %s\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom),
- oldSrcPath, newSrcPath, devAlias, diskChangeReasonToStr(reason));
- return 0;
-}
-
-static const char *
-trayChangeReasonToStr(int reason)
-{
- switch ((virDomainEventTrayChangeReason) reason) {
- case VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN:
- return "open";
-
- case VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE:
- return "close";
-
- case VIR_DOMAIN_EVENT_TRAY_CHANGE_LAST:
- break;
- }
-
- return "unknown";
-};
-
-
-static int
-myDomainEventTrayChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *devAlias,
- int reason,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) removable disk's tray change devAlias: %s "
- "reason: %s\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom),
- devAlias, trayChangeReasonToStr(reason));
- return 0;
-}
-
-
-static int
-myDomainEventPMWakeupCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) system pmwakeup\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom));
- return 0;
-}
-
-
-static int
-myDomainEventPMSuspendCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) system pmsuspend\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom));
- return 0;
-}
-
-
-static int
-myDomainEventPMSuspendDiskCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int reason ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) system pmsuspend-disk\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom));
- return 0;
-}
-
-
-static int
-myDomainEventDeviceRemovedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *devAlias,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) device removed: %s\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom), devAlias);
- return 0;
-}
-
-
-static int
-myNetworkEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virNetworkPtr dom,
- int event,
- int detail,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Network %s %s %d\n", __func__, virNetworkGetName(dom),
- networkEventToString(event), detail);
- return 0;
-}
-
-static int
-myStoragePoolEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virStoragePoolPtr pool,
- int event,
- int detail,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Storage pool %s %s %d\n", __func__,
- virStoragePoolGetName(pool),
- storagePoolEventToString(event),
- detail);
- return 0;
-}
-
-
-static int
-myStoragePoolEventRefreshCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virStoragePoolPtr pool,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Storage pool %s refresh\n", __func__,
- virStoragePoolGetName(pool));
- return 0;
-}
-
-
-static int
-myNodeDeviceEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virNodeDevicePtr dev,
- int event,
- int detail,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Node device %s %s %d\n", __func__,
- virNodeDeviceGetName(dev),
- nodeDeviceEventToString(event),
- detail);
- return 0;
-}
-
-
-static int
-myNodeDeviceEventUpdateCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virNodeDevicePtr dev,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Node device %s update\n", __func__,
- virNodeDeviceGetName(dev));
- return 0;
-}
-
-
-static int
-mySecretEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virSecretPtr secret,
- int event,
- int detail,
- void *opaque ATTRIBUTE_UNUSED)
-{
- char uuid[VIR_UUID_STRING_BUFLEN];
- virSecretGetUUIDString(secret, uuid);
- printf("%s EVENT: Secret %s %s %d\n", __func__,
- uuid,
- secretEventToString(event),
- detail);
- return 0;
-}
-
-
-static int
-mySecretEventValueChanged(virConnectPtr conn ATTRIBUTE_UNUSED,
- virSecretPtr secret,
- void *opaque ATTRIBUTE_UNUSED)
-{
- char uuid[VIR_UUID_STRING_BUFLEN];
- virSecretGetUUIDString(secret, uuid);
- printf("%s EVENT: Secret %s\n", __func__, uuid);
- return 0;
-}
-
-
-static void
-eventTypedParamsPrint(virTypedParameterPtr params,
- int nparams)
-{
- size_t i;
-
- for (i = 0; i < nparams; i++) {
- switch (params[i].type) {
- case VIR_TYPED_PARAM_INT:
- printf("\t%s: %d\n", params[i].field, params[i].value.i);
- break;
- case VIR_TYPED_PARAM_UINT:
- printf("\t%s: %u\n", params[i].field, params[i].value.ui);
- break;
- case VIR_TYPED_PARAM_LLONG:
- printf("\t%s: %" PRId64 "\n", params[i].field,
- (int64_t) params[i].value.l);
- break;
- case VIR_TYPED_PARAM_ULLONG:
- printf("\t%s: %" PRIu64 "\n", params[i].field,
- (uint64_t) params[i].value.ul);
- break;
- case VIR_TYPED_PARAM_DOUBLE:
- printf("\t%s: %g\n", params[i].field, params[i].value.d);
- break;
- case VIR_TYPED_PARAM_BOOLEAN:
- printf("\t%s: %d\n", params[i].field, params[i].value.b);
- break;
- case VIR_TYPED_PARAM_STRING:
- printf("\t%s: %s\n", params[i].field, params[i].value.s);
- break;
- default:
- printf("\t%s: unknown type\n", params[i].field);
- }
- }
-}
-
-
-static int
-myDomainEventTunableCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- virTypedParameterPtr params,
- int nparams,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) tunable updated:\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom));
-
- eventTypedParamsPrint(params, nparams);
-
- return 0;
-}
-
-
-static int
-myDomainEventAgentLifecycleCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int state,
- int reason,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) guest agent state changed: %s reason: %s\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom),
- guestAgentLifecycleEventStateToString(state),
- guestAgentLifecycleEventReasonToString(reason));
-
- return 0;
-}
-
-
-static int
-myDomainEventDeviceAddedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *devAlias,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) device added: %s\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom), devAlias);
- return 0;
-}
-
-
-static const char *
-blockJobTypeToStr(int type)
-{
- switch ((virDomainBlockJobType) type) {
- case VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN:
- case VIR_DOMAIN_BLOCK_JOB_TYPE_LAST:
- break;
-
- case VIR_DOMAIN_BLOCK_JOB_TYPE_PULL:
- return "block pull";
-
- case VIR_DOMAIN_BLOCK_JOB_TYPE_COPY:
- return "block copy";
-
- case VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT:
- return "block commit";
-
- case VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT:
- return "active layer block commit";
- }
-
- return "unknown";
-}
-
-
-static const char *
-blockJobStatusToStr(int status)
-{
- switch ((virConnectDomainEventBlockJobStatus) status) {
- case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
- return "completed";
-
- case VIR_DOMAIN_BLOCK_JOB_FAILED:
- return "failed";
-
- case VIR_DOMAIN_BLOCK_JOB_CANCELED:
- return "cancelled";
-
- case VIR_DOMAIN_BLOCK_JOB_READY:
- return "ready";
-
- case VIR_DOMAIN_BLOCK_JOB_LAST:
- break;
- }
-
- return "unknown";
-}
-
-
-static int
-myDomainEventBlockJobCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *disk,
- int type,
- int status,
- void *opaque)
-{
- const char *eventName = opaque;
-
- printf("%s EVENT: Domain %s(%d) block job callback '%s' disk '%s', "
- "type '%s' status '%s'",
- __func__, virDomainGetName(dom), virDomainGetID(dom), eventName,
- disk, blockJobTypeToStr(type), blockJobStatusToStr(status));
- return 0;
-}
-
-
-static int
-myDomainEventBlockThresholdCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *dev,
- const char *path,
- unsigned long long threshold,
- unsigned long long excess,
- void *opaque ATTRIBUTE_UNUSED)
-{
- /* Casts to uint64_t to work around mingw not knowing %lld */
- printf("%s EVENT: Domain %s(%d) block threshold callback dev '%s'(%s), "
- "threshold: '%" PRIu64 "', excess: '%" PRIu64 "'",
- __func__, virDomainGetName(dom), virDomainGetID(dom),
- dev, NULLSTR(path), (uint64_t)threshold, (uint64_t)excess);
- return 0;
-}
-
-
-static int
-myDomainEventMigrationIterationCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int iteration,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) migration iteration '%d'\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom), iteration);
- return 0;
-}
-
-
-static int
-myDomainEventJobCompletedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- virTypedParameterPtr params,
- int nparams,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) job completed:\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom));
-
- eventTypedParamsPrint(params, nparams);
-
- return 0;
-}
-
-
-static int
-myDomainEventDeviceRemovalFailedCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- const char *devAlias,
- void *opaque ATTRIBUTE_UNUSED)
-{
- printf("%s EVENT: Domain %s(%d) device removal failed: %s\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom), devAlias);
- return 0;
-}
-
-
-static const char *
-metadataTypeToStr(int status)
-{
- switch ((virDomainMetadataType) status) {
- case VIR_DOMAIN_METADATA_DESCRIPTION:
- return "description";
-
- case VIR_DOMAIN_METADATA_TITLE:
- return "title";
-
- case VIR_DOMAIN_METADATA_ELEMENT:
- return "element";
-
- case VIR_DOMAIN_METADATA_LAST:
- break;
- }
-
- return "unknown";
-}
-
-static int
-myDomainEventMetadataChangeCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
- virDomainPtr dom,
- int type,
- const char *nsuri,
- void *opaque ATTRIBUTE_UNUSED)
-{
- const char *typestr = metadataTypeToStr(type);
- printf("%s EVENT: Domain %s(%d) metadata type: %s (%s)\n",
- __func__, virDomainGetName(dom), virDomainGetID(dom), typestr, nsuri ? nsuri : "n/a");
- return 0;
-}
-
-
-
-static void
-myFreeFunc(void *opaque)
-{
- char *str = opaque;
- printf("%s: Freeing [%s]\n", __func__, str);
- free(str);
-}
-
-
-/* main test functions */
-static void
-stop(int sig)
-{
- printf("Exiting on signal %d\n", sig);
- run = 0;
-}
-
-
-struct domainEventData {
- int event;
- int id;
- virConnectDomainEventGenericCallback cb;
- const char *name;
-};
-
-
-#define DOMAIN_EVENT(event, callback) \
- {event, -1, VIR_DOMAIN_EVENT_CALLBACK(callback), #event}
-
-struct domainEventData domainEvents[] = {
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback2),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_REBOOT, myDomainEventRebootCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_RTC_CHANGE, myDomainEventRTCChangeCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_WATCHDOG, myDomainEventWatchdogCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_IO_ERROR, myDomainEventIOErrorCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_GRAPHICS, myDomainEventGraphicsCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON, myDomainEventIOErrorReasonCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_CONTROL_ERROR, myDomainEventControlErrorCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_JOB, myDomainEventBlockJobCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DISK_CHANGE, myDomainEventDiskChangeCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, myDomainEventTrayChangeCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_PMWAKEUP, myDomainEventPMWakeupCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_PMSUSPEND, myDomainEventPMSuspendCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, myDomainEventBalloonChangeCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK, myDomainEventPMSuspendDiskCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, myDomainEventDeviceRemovedCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2, myDomainEventBlockJobCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_TUNABLE, myDomainEventTunableCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE, myDomainEventAgentLifecycleCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DEVICE_ADDED, myDomainEventDeviceAddedCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION, myDomainEventMigrationIterationCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_JOB_COMPLETED, myDomainEventJobCompletedCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED, myDomainEventDeviceRemovalFailedCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_METADATA_CHANGE, myDomainEventMetadataChangeCallback),
- DOMAIN_EVENT(VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD, myDomainEventBlockThresholdCallback),
-};
-
-struct storagePoolEventData {
- int event;
- int id;
- virConnectStoragePoolEventGenericCallback cb;
- const char *name;
-};
-
-#define STORAGE_POOL_EVENT(event, callback) \
- {event, -1, VIR_STORAGE_POOL_EVENT_CALLBACK(callback), #event}
-
-struct storagePoolEventData storagePoolEvents[] = {
- STORAGE_POOL_EVENT(VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE, myStoragePoolEventCallback),
- STORAGE_POOL_EVENT(VIR_STORAGE_POOL_EVENT_ID_REFRESH, myStoragePoolEventRefreshCallback),
-};
-
-struct nodeDeviceEventData {
- int event;
- int id;
- virConnectNodeDeviceEventGenericCallback cb;
- const char *name;
-};
-
-#define NODE_DEVICE_EVENT(event, callback) \
- {event, -1, VIR_NODE_DEVICE_EVENT_CALLBACK(callback), #event}
-
-struct nodeDeviceEventData nodeDeviceEvents[] = {
- NODE_DEVICE_EVENT(VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE, myNodeDeviceEventCallback),
- NODE_DEVICE_EVENT(VIR_NODE_DEVICE_EVENT_ID_UPDATE, myNodeDeviceEventUpdateCallback),
-};
-
-struct secretEventData {
- int event;
- int id;
- virConnectSecretEventGenericCallback cb;
- const char *name;
-};
-
-#define SECRET_EVENT(event, callback) \
- {event, -1, VIR_SECRET_EVENT_CALLBACK(callback), #event}
-
-struct secretEventData secretEvents[] = {
- SECRET_EVENT(VIR_SECRET_EVENT_ID_LIFECYCLE, mySecretEventCallback),
- SECRET_EVENT(VIR_SECRET_EVENT_ID_VALUE_CHANGED, mySecretEventValueChanged),
-};
-
-/* make sure that the events are kept in sync */
-verify(ARRAY_CARDINALITY(domainEvents) == VIR_DOMAIN_EVENT_ID_LAST);
-verify(ARRAY_CARDINALITY(storagePoolEvents) == VIR_STORAGE_POOL_EVENT_ID_LAST);
-verify(ARRAY_CARDINALITY(nodeDeviceEvents) == VIR_NODE_DEVICE_EVENT_ID_LAST);
-verify(ARRAY_CARDINALITY(secretEvents) == VIR_SECRET_EVENT_ID_LAST);
-
-int
-main(int argc, char **argv)
-{
- int ret = EXIT_FAILURE;
- virConnectPtr dconn = NULL;
- int callback1ret = -1;
- int callback16ret = -1;
- size_t i;
-
- if (argc > 1 && STREQ(argv[1], "--help")) {
- printf("%s uri\n", argv[0]);
- goto cleanup;
- }
-
- if (virInitialize() < 0) {
- fprintf(stderr, "Failed to initialize libvirt");
- goto cleanup;
- }
-
- if (virEventRegisterDefaultImpl() < 0) {
- fprintf(stderr, "Failed to register event implementation: %s\n",
- virGetLastErrorMessage());
- goto cleanup;
- }
-
- dconn = virConnectOpenAuth(argc > 1 ? argv[1] : NULL,
- virConnectAuthPtrDefault,
- VIR_CONNECT_RO);
- if (!dconn) {
- printf("error opening\n");
- goto cleanup;
- }
-
- if (virConnectRegisterCloseCallback(dconn,
- connectClose, NULL, NULL) < 0) {
- fprintf(stderr, "Unable to register close callback\n");
- goto cleanup;
- }
-
- /* The ideal program would use sigaction to set this handler, but
- * this way is portable to mingw. */
- signal(SIGTERM, stop);
- signal(SIGINT, stop);
-
- printf("Registering event callbacks\n");
-
- callback1ret = virConnectDomainEventRegister(dconn, myDomainEventCallback1,
- strdup("callback 1"), myFreeFunc);
-
- /* register common domain callbacks */
- for (i = 0; i < ARRAY_CARDINALITY(domainEvents); i++) {
- struct domainEventData *event = domainEvents + i;
-
- event->id = virConnectDomainEventRegisterAny(dconn, NULL,
- event->event,
- event->cb,
- strdup(event->name),
- myFreeFunc);
-
- if (event->id < 0) {
- fprintf(stderr, "Failed to register event '%s'\n", event->name);
- goto cleanup;
- }
- }
-
- callback16ret = virConnectNetworkEventRegisterAny(dconn,
- NULL,
- VIR_NETWORK_EVENT_ID_LIFECYCLE,
- VIR_NETWORK_EVENT_CALLBACK(myNetworkEventCallback),
- strdup("net callback"), myFreeFunc);
-
- /* register common storage pool callbacks */
- for (i = 0; i < ARRAY_CARDINALITY(storagePoolEvents); i++) {
- struct storagePoolEventData *event = storagePoolEvents + i;
-
- event->id = virConnectStoragePoolEventRegisterAny(dconn, NULL,
- event->event,
- event->cb,
- strdup(event->name),
- myFreeFunc);
-
- if (event->id < 0) {
- fprintf(stderr, "Failed to register event '%s'\n", event->name);
- goto cleanup;
- }
- }
-
- /* register common node device callbacks */
- for (i = 0; i < ARRAY_CARDINALITY(nodeDeviceEvents); i++) {
- struct nodeDeviceEventData *event = nodeDeviceEvents + i;
-
- event->id = virConnectNodeDeviceEventRegisterAny(dconn, NULL,
- event->event,
- event->cb,
- strdup(event->name),
- myFreeFunc);
-
- if (event->id < 0) {
- fprintf(stderr, "Failed to register event '%s'\n", event->name);
- goto cleanup;
- }
- }
-
- /* register common secret callbacks */
- for (i = 0; i < ARRAY_CARDINALITY(secretEvents); i++) {
- struct secretEventData *event = secretEvents + i;
-
- event->id = virConnectSecretEventRegisterAny(dconn, NULL,
- event->event,
- event->cb,
- strdup(event->name),
- myFreeFunc);
-
- if (event->id < 0) {
- fprintf(stderr, "Failed to register event '%s'\n", event->name);
- goto cleanup;
- }
- }
-
- if ((callback1ret == -1) ||
- (callback16ret == -1))
- goto cleanup;
-
- if (virConnectSetKeepAlive(dconn, 5, 3) < 0) {
- fprintf(stderr, "Failed to start keepalive protocol: %s\n",
- virGetLastErrorMessage());
- run = 0;
- }
-
- while (run) {
- if (virEventRunDefaultImpl() < 0) {
- fprintf(stderr, "Failed to run event loop: %s\n",
- virGetLastErrorMessage());
- }
- }
-
- printf("Deregistering event callbacks\n");
- virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
- virConnectNetworkEventDeregisterAny(dconn, callback16ret);
-
-
- printf("Deregistering domain event callbacks\n");
- for (i = 0; i < ARRAY_CARDINALITY(domainEvents); i++) {
- if (domainEvents[i].id > 0)
- virConnectDomainEventDeregisterAny(dconn, domainEvents[i].id);
- }
-
-
- printf("Deregistering storage pool event callbacks\n");
- for (i = 0; i < ARRAY_CARDINALITY(storagePoolEvents); i++) {
- if (storagePoolEvents[i].id > 0)
- virConnectStoragePoolEventDeregisterAny(dconn, storagePoolEvents[i].id);
- }
-
-
- printf("Deregistering node device event callbacks\n");
- for (i = 0; i < ARRAY_CARDINALITY(nodeDeviceEvents); i++) {
- if (nodeDeviceEvents[i].id > 0)
- virConnectNodeDeviceEventDeregisterAny(dconn, nodeDeviceEvents[i].id);
- }
-
- printf("Deregistering secret event callbacks\n");
- for (i = 0; i < ARRAY_CARDINALITY(secretEvents); i++) {
- if (secretEvents[i].id > 0)
- virConnectSecretEventDeregisterAny(dconn, secretEvents[i].id);
- }
-
-
- virConnectUnregisterCloseCallback(dconn, connectClose);
- ret = EXIT_SUCCESS;
-
-
- cleanup:
- if (dconn) {
- printf("Closing connection: ");
- if (virConnectClose(dconn) < 0)
- printf("failed\n");
- printf("done\n");
- }
-
- return ret;
-}
+++ /dev/null
-/* This file contains trivial example code to connect to the running
- * hypervisor and gather a few bits of information about domains.
- * Similar API's exist for storage pools, networks, and interfaces. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <libvirt/libvirt.h>
-#include <libvirt/virterror.h>
-
-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 (!hvType) {
- ret = 1;
- printf("Failed to get hypervisor type: %s\n",
- virGetLastErrorMessage());
- goto out;
- }
-
- if (0 != virConnectGetVersion(conn, &hvVer)) {
- ret = 1;
- printf("Failed to get hypervisor version: %s\n",
- virGetLastErrorMessage());
- 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, numNames, numInactiveDomains, numActiveDomains;
- ssize_t i;
- int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE |
- VIR_CONNECT_LIST_DOMAINS_INACTIVE;
- virDomainPtr *nameList = NULL;
-
- /* NB: The return from the virConnectNum*() APIs is only useful for
- * the current call. A domain could be started or stopped and any
- * assumptions made purely on these return values could result in
- * unexpected results */
- numActiveDomains = virConnectNumOfDomains(conn);
- if (numActiveDomains == -1) {
- ret = 1;
- printf("Failed to get number of active domains: %s\n",
- virGetLastErrorMessage());
- goto out;
- }
-
- numInactiveDomains = virConnectNumOfDefinedDomains(conn);
- if (numInactiveDomains == -1) {
- ret = 1;
- printf("Failed to get number of inactive domains: %s\n",
- virGetLastErrorMessage());
- goto out;
- }
-
- printf("There are %d active and %d inactive domains\n",
- numActiveDomains, numInactiveDomains);
-
- /* Return a list of all active and inactive domains. Using this API
- * instead of virConnectListDomains() and virConnectListDefinedDomains()
- * is preferred since it "solves" an inherit race between separated API
- * calls if domains are started or stopped between calls */
- numNames = virConnectListAllDomains(conn,
- &nameList,
- flags);
- if (numNames == -1) {
- ret = 1;
- printf("Failed to get a list of all domains: %s\n",
- virGetLastErrorMessage());
- goto out;
- }
-
- for (i = 0; i < numNames; i++) {
- int active = virDomainIsActive(nameList[i]);
- printf(" %8s (%s)\n",
- virDomainGetName(nameList[i]),
- (active == 1 ? "active" : "non-active"));
- /* must free the returned named per the API documentation */
- virDomainFree(nameList[i]);
- }
- free(nameList);
-
- out:
- 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 (!conn) {
- ret = 1;
- printf("No connection to hypervisor: %s\n",
- virGetLastErrorMessage());
- goto out;
- }
-
- uri = virConnectGetURI(conn);
- if (!uri) {
- ret = 1;
- printf("Failed to get URI for hypervisor connection: %s\n",
- virGetLastErrorMessage());
- 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: %s\n",
- virGetLastErrorMessage());
- ret = 1;
- } else {
- printf("Disconnected from hypervisor\n");
- }
-
- out:
- return ret;
-}
+++ /dev/null
-/* This is a copy of the hellolibvirt example demonstaring how to use
- * virConnectOpenAuth with a custom auth callback */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libvirt/libvirt.h>
-#include <libvirt/virterror.h>
-
-static void
-showError(virConnectPtr conn)
-{
- int ret;
- virErrorPtr err;
-
- err = malloc(sizeof(*err));
- if (err == NULL) {
- 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 (hvType == NULL) {
- ret = 1;
- printf("Failed to get hypervisor type\n");
- showError(conn);
- goto out;
- }
-
- if (virConnectGetVersion(conn, &hvVer) != 0) {
- 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, numNames, numInactiveDomains, numActiveDomains;
- ssize_t i;
- char **nameList = NULL;
-
- numActiveDomains = virConnectNumOfDomains(conn);
- if (numActiveDomains == -1) {
- ret = 1;
- printf("Failed to get number of active domains\n");
- showError(conn);
- goto out;
- }
-
- numInactiveDomains = virConnectNumOfDefinedDomains(conn);
- if (numInactiveDomains == -1) {
- 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 (nameList == NULL) {
- ret = 1;
- printf("Could not allocate memory for list of inactive domains\n");
- goto out;
- }
-
- numNames = virConnectListDefinedDomains(conn,
- nameList,
- numInactiveDomains);
-
- if (numNames == -1) {
- 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;
-}
-
-/* Struct to pass the credentials to the auth callback via the cbdata pointer */
-struct _AuthData {
- char *username;
- char *password;
-};
-
-typedef struct _AuthData AuthData;
-
-/* This function will be called by libvirt to obtain credentials in order to
- * authenticate to the hypervisor */
-static int
-authCallback(virConnectCredentialPtr cred, unsigned int ncred, void *cbdata)
-{
- size_t i;
- AuthData *authData = cbdata;
-
- /* libvirt might request multiple credentials in a single call.
- * This example supports VIR_CRED_AUTHNAME and VIR_CRED_PASSPHRASE
- * credentials only, but there are several other types.
- *
- * A request may also contain a prompt message that can be displayed
- * to the user and a challenge. The challenge is specific to the
- * credential type and hypervisor type.
- *
- * For example the ESX driver passes the hostname of the ESX or vCenter
- * server as challenge. This allows a auth callback to return the
- * proper credentials. */
- for (i = 0; i < ncred; ++i) {
- switch (cred[i].type) {
- case VIR_CRED_AUTHNAME:
- cred[i].result = strdup(authData->username);
-
- if (cred[i].result == NULL)
- return -1;
-
- cred[i].resultlen = strlen(cred[i].result);
- break;
-
- case VIR_CRED_PASSPHRASE:
- cred[i].result = strdup(authData->password);
-
- if (cred[i].result == NULL)
- return -1;
-
- cred[i].resultlen = strlen(cred[i].result);
- break;
-
- default:
- return -1;
- }
- }
-
- return 0;
-}
-
-
-/* The list of credential types supported by our auth callback */
-static int credTypes[] = {
- VIR_CRED_AUTHNAME,
- VIR_CRED_PASSPHRASE
-};
-
-
-/* The auth struct that will be passed to virConnectOpenAuth */
-static virConnectAuth auth = {
- credTypes,
- sizeof(credTypes) / sizeof(int),
- authCallback,
- NULL, /* cbdata will be initialized in main */
-};
-
-
-int
-main(int argc, char *argv[])
-{
- int ret = 0;
- virConnectPtr conn;
- char *uri;
- AuthData authData;
-
- if (argc != 4) {
- ret = 1;
- printf("Usage: %s <uri> <username> <password>\n", argv[0]);
- goto out;
- }
-
- uri = argv[1];
- authData.username = argv[2];
- authData.password = argv[3];
- auth.cbdata = &authData;
-
- printf("Attempting to connect to hypervisor\n");
-
- conn = virConnectOpenAuth(uri, &auth, 0);
-
- if (NULL == conn) {
- ret = 1;
- printf("No connection to hypervisor\n");
- showError(conn);
- goto out;
- }
-
- uri = virConnectGetURI(conn);
- if (uri == NULL) {
- 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 (showHypervisorInfo(conn) != 0) {
- ret = 1;
- goto disconnect;
- }
-
- if (showDomains(conn) != 0) {
- ret = 1;
- goto disconnect;
- }
-
- disconnect:
- if (virConnectClose(conn) != 0) {
- printf("Failed to disconnect from hypervisor\n");
- showError(conn);
- ret = 1;
- } else {
- printf("Disconnected from hypervisor\n");
- }
-
- out:
- return ret;
-}