This partially reverts 5eb4b04211 and 62774afb6ba8.
Rewrite the domsuspend example from scratch. This time do it right.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
.gitignore | 1 +
Makefile.am | 4 +-
cfg.mk | 2 +-
configure.ac | 1 +
examples/domsuspend/Makefile.am | 27 ++++
examples/domsuspend/suspend.c | 276 ++++++++++++++++++++++++++++++++++++++++
libvirt.spec.in | 3 +-
7 files changed, 310 insertions(+), 4 deletions(-)
create mode 100644 examples/domsuspend/Makefile.am
create mode 100644 examples/domsuspend/suspend.c
diff --git a/.gitignore b/.gitignore
index 2d364dc..fbb2c01 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,6 +71,7 @@
/docs/todo.html.in
/examples/domain-events/events-c/event-test
/examples/dominfo/info1
+/examples/domsuspend/suspend
/examples/hellolibvirt/hellolibvirt
/examples/openauth/openauth
/gnulib/lib/*
diff --git a/Makefile.am b/Makefile.am
index 2cbf71a..d7ddd9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,8 +21,8 @@ GENHTML = genhtml
SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \
tests po examples/domain-events/events-c examples/hellolibvirt \
- examples/dominfo examples/apparmor examples/xml/nwfilter \
- examples/openauth examples/systemtap
+ examples/dominfo examples/domsuspend examples/apparmor \
+ examples/xml/nwfilter examples/openauth examples/systemtap
ACLOCAL_AMFLAGS = -I m4
diff --git a/cfg.mk b/cfg.mk
index fe760a9..67fc432 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -1003,7 +1003,7 @@ exclude_file_name_regexp--sc_prohibit_sprintf = \
exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virstring\.c$$
exclude_file_name_regexp--sc_prohibit_strtol = \
- ^src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c$$
+ ^(src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c)|(examples/domsuspend/suspend.c)$$
exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$
diff --git a/configure.ac b/configure.ac
index bb92349..cc485d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2555,6 +2555,7 @@ AC_CONFIG_FILES([\
tests/Makefile \
examples/apparmor/Makefile \
examples/domain-events/events-c/Makefile \
+ examples/domsuspend/Makefile \
examples/dominfo/Makefile \
examples/openauth/Makefile \
examples/hellolibvirt/Makefile \
diff --git a/examples/domsuspend/Makefile.am b/examples/domsuspend/Makefile.am
new file mode 100644
index 0000000..b8e65f2
--- /dev/null
+++ b/examples/domsuspend/Makefile.am
@@ -0,0 +1,27 @@
+## Process this file with automake to produce Makefile.in
+
+## Copyright (C) 2013 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/>.
+
+INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+LDADDS = $(STATIC_BINARIES) $(WARN_CFLAGS) $(top_builddir)/src/libvirt.la \
+ $(COVERAGE_LDFLAGS)
+
+noinst_PROGRAMS=suspend
+
+suspend_SOURCES=suspend.c
+suspend_LDFLAGS=
+suspend_LDADD= $(LDADDS)
diff --git a/examples/domsuspend/suspend.c b/examples/domsuspend/suspend.c
new file mode 100644
index 0000000..ba9dd6e
--- /dev/null
+++ b/examples/domsuspend/suspend.c
@@ -0,0 +1,276 @@
+/*
+ * 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/>.
+ *
+ * Author: Michal Privoznik <mprivozn(a)redhat.com>
+ */
+
+#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>
+
+int debug = 0;
+
+#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;
+ size_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 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;
+}
diff --git a/libvirt.spec.in b/libvirt.spec.in
index f615c62..8867ebc 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1430,7 +1430,7 @@ rm -fr %{buildroot}
# on RHEL 5, thus we need to expand it here.
make install DESTDIR=%{?buildroot} SYSTEMD_UNIT_DIR=%{_unitdir}
-for i in domain-events/events-c dominfo hellolibvirt openauth xml/nwfilter systemtap
+for i in domain-events/events-c dominfo domsuspend hellolibvirt openauth xml/nwfilter
systemtap
do
(cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in)
done
@@ -2134,6 +2134,7 @@ exit 0
%doc examples/hellolibvirt
%doc examples/domain-events/events-c
%doc examples/dominfo
+%doc examples/domsuspend
%doc examples/openauth
%doc examples/xml
%doc examples/systemtap
--
1.8.5.1