mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-30 16:35:24 +00:00
examples: Resurrect domsuspend example
This partially reverts 5eb4b04211 and 62774afb6ba8. Rewrite the domsuspend example from scratch. This time do it right. Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
9375ba2a6e
commit
e26cae6b85
1
.gitignore
vendored
1
.gitignore
vendored
@ -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/*
|
||||
|
@ -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
2
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$$
|
||||
|
||||
|
@ -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 \
|
||||
|
27
examples/domsuspend/Makefile.am
Normal file
27
examples/domsuspend/Makefile.am
Normal 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)
|
276
examples/domsuspend/suspend.c
Normal file
276
examples/domsuspend/suspend.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user