examples: Resurrect domsuspend example

This partially reverts 5eb4b04211 and 62774afb6b.

Rewrite the domsuspend example from scratch. This time do it right.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2013-12-13 12:54:10 +01:00
parent 9375ba2a6e
commit e26cae6b85
7 changed files with 310 additions and 4 deletions

1
.gitignore vendored
View File

@ -71,6 +71,7 @@
/docs/todo.html.in
/examples/object-events/event-test
/examples/dominfo/info1
/examples/domsuspend/suspend
/examples/hellolibvirt/hellolibvirt
/examples/openauth/openauth
/gnulib/lib/*

View File

@ -21,8 +21,8 @@ GENHTML = genhtml
SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \
tests po examples/object-events 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

2
cfg.mk
View File

@ -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$$

View File

@ -2555,6 +2555,7 @@ AC_CONFIG_FILES([\
tests/Makefile \
examples/apparmor/Makefile \
examples/object-events/Makefile \
examples/domsuspend/Makefile \
examples/dominfo/Makefile \
examples/openauth/Makefile \
examples/hellolibvirt/Makefile \

View File

@ -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)

View File

@ -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@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>
static int debug;
#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 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;
}

View File

@ -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 object-events dominfo hellolibvirt openauth xml/nwfilter systemtap
for i in object-events dominfo domsuspend hellolibvirt openauth xml/nwfilter systemtap
do
(cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in)
done
@ -2142,6 +2142,7 @@ exit 0
%doc examples/hellolibvirt
%doc examples/object-events
%doc examples/dominfo
%doc examples/domsuspend
%doc examples/openauth
%doc examples/xml
%doc examples/systemtap