[libvirt] [PATCH libvirt-tck] bhyve: reconnect to domains after libvirtd restart
by Roman Bogorodskiy
Try to reconnect to the running domains after libvirtd restart. To
achieve that, do:
* Save domain state
- Modify virBhyveProcessStart() to save domain state to the state
dir
- Modify virBhyveProcessStop() to cleanup the pidfile and the state
* Detect if the state information loaded from the driver's state
dir matches the actual state. Consider domain active if:
- PID it points to exist
- Process title of this PID matches the expected one with the
domain name
Otherwise, mark the domain as shut off.
Note: earlier development bhyve versions before FreeBSD 10.0-RELEASE
didn't set proctitle we expect, so the current code will not detect
it. I don't plan adding support for this unless somebody requests
this.
---
src/bhyve/bhyve_driver.c | 18 ++++++++++
src/bhyve/bhyve_process.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++
src/bhyve/bhyve_process.h | 2 ++
3 files changed, 111 insertions(+)
diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index eb5fc95..4c7596e 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1151,6 +1151,8 @@ bhyveStateInitialize(bool priveleged ATTRIBUTE_UNUSED,
virStateInhibitCallback callback ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED)
{
+ virConnectPtr conn = NULL;
+
if (!priveleged) {
VIR_INFO("Not running priveleged, disabling driver");
return 0;
@@ -1199,6 +1201,15 @@ bhyveStateInitialize(bool priveleged ATTRIBUTE_UNUSED,
}
if (virDomainObjListLoadAllConfigs(bhyve_driver->domains,
+ BHYVE_STATE_DIR,
+ NULL, 1,
+ bhyve_driver->caps,
+ bhyve_driver->xmlopt,
+ 1 << VIR_DOMAIN_VIRT_BHYVE,
+ NULL, NULL) < 0)
+ goto cleanup;
+
+ if (virDomainObjListLoadAllConfigs(bhyve_driver->domains,
BHYVE_CONFIG_DIR,
BHYVE_AUTOSTART_DIR, 0,
bhyve_driver->caps,
@@ -1207,9 +1218,16 @@ bhyveStateInitialize(bool priveleged ATTRIBUTE_UNUSED,
NULL, NULL) < 0)
goto cleanup;
+ conn = virConnectOpen("bhyve:///system");
+
+ virBhyveProcessReconnectAll(conn, bhyve_driver);
+
+ virObjectUnref(conn);
+
return 0;
cleanup:
+ virObjectUnref(conn);
bhyveStateCleanup();
return -1;
}
diff --git a/src/bhyve/bhyve_process.c b/src/bhyve/bhyve_process.c
index f3898f5..ea5ac9b 100644
--- a/src/bhyve/bhyve_process.c
+++ b/src/bhyve/bhyve_process.c
@@ -185,6 +185,11 @@ virBhyveProcessStart(virConnectPtr conn,
vm->def->id = vm->pid;
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
+ if (virDomainSaveStatus(driver->xmlopt,
+ BHYVE_STATE_DIR,
+ vm) < 0)
+ goto cleanup;
+
ret = 0;
cleanup:
@@ -257,6 +262,10 @@ virBhyveProcessStop(bhyveConnPtr driver,
cleanup:
virCommandFree(cmd);
+
+ virPidFileDelete(BHYVE_STATE_DIR, vm->def->name);
+ virDomainDeleteConfig(BHYVE_STATE_DIR, NULL, vm);
+
return ret;
}
@@ -295,3 +304,85 @@ virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm,
return ret;
}
+
+struct bhyveProcessReconnectData {
+ virConnectPtr conn;
+ bhyveConnPtr driver;
+ kvm_t *kd;
+};
+
+static int
+virBhyveProcessReconnect(virDomainObjPtr vm,
+ void *opaque)
+{
+ struct bhyveProcessReconnectData *data = opaque;
+ struct kinfo_proc *kp;
+ int nprocs;
+ char **proc_argv;
+ char *expected_proctitle = NULL;
+ int ret = -1;
+
+ if (!virDomainObjIsActive(vm))
+ return 0;
+
+ if (!vm->pid)
+ return 0;
+
+ virObjectLock(vm);
+
+ kp = kvm_getprocs(data->kd, KERN_PROC_PID, vm->pid, &nprocs);
+ if (kp == NULL || nprocs != 1)
+ goto cleanup;
+
+ if (virAsprintf(&expected_proctitle, "bhyve: %s", vm->def->name) < 0)
+ goto cleanup;
+
+ proc_argv = kvm_getargv(data->kd, kp, 0);
+ if (proc_argv && proc_argv[0])
+ if (STREQ(expected_proctitle, proc_argv[0]))
+ ret = 0;
+
+ cleanup:
+ if (ret < 0) {
+ /* If VM is reported to be in active state, but we cannot find
+ * its PID, then we clear information about the PID and
+ * set state to 'shutdown' */
+ vm->pid = 0;
+ vm->def->id = -1;
+ virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF,
+ VIR_DOMAIN_SHUTOFF_UNKNOWN);
+ ignore_value(virDomainSaveStatus(data->driver->xmlopt,
+ BHYVE_STATE_DIR,
+ vm));
+ }
+
+ virObjectUnlock(vm);
+ VIR_FREE(expected_proctitle);
+
+ return ret;
+}
+
+void
+virBhyveProcessReconnectAll(virConnectPtr conn,
+ bhyveConnPtr driver)
+{
+ kvm_t *kd;
+ struct bhyveProcessReconnectData data;
+ char errbuf[_POSIX2_LINE_MAX];
+
+ if ((kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf)) == NULL) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("Unable to get kvm descriptor: %s"),
+ errbuf);
+ return;
+
+ }
+
+ data.conn = conn;
+ data.driver = driver;
+ data.kd = kd;
+
+ virDomainObjListForEach(driver->domains, virBhyveProcessReconnect, &data);
+
+ kvm_close(kd);
+}
diff --git a/src/bhyve/bhyve_process.h b/src/bhyve/bhyve_process.h
index 3049ad0..006a5ae 100644
--- a/src/bhyve/bhyve_process.h
+++ b/src/bhyve/bhyve_process.h
@@ -37,6 +37,8 @@ int virBhyveProcessStop(bhyveConnPtr driver,
int virBhyveGetDomainTotalCpuStats(virDomainObjPtr vm,
unsigned long long *cpustats);
+void virBhyveProcessReconnectAll(virConnectPtr conn, bhyveConnPtr driver);
+
typedef enum {
VIR_BHYVE_PROCESS_START_AUTODESTROY = 1 << 0,
} bhyveProcessStartFlags;
--
1.9.0
10 years, 11 months
[libvirt] [PATCH 0/2] Fix docs and handling of snapshots on SCSI passthrough devices
by Peter Krempa
Libvirt didn't catch an attempt to do a snapshot of a SCSI passthrough disk
when backed by iSCSI and the docs didn't state that disk type 'lun' works also
with iSCSI.
Peter Krempa (2):
doc: domain: Clarify that disk type 'lun' works with iSCSI too
qemu: snapshot: Forbid snapshots of iSCSI passthrough devices
docs/formatdomain.html.in | 3 ++-
src/qemu/qemu_driver.c | 5 +----
2 files changed, 3 insertions(+), 5 deletions(-)
--
2.0.0
10 years, 11 months
[libvirt] [PATCH v2] examples: Introduce domtop
by Michal Privoznik
There's this question on the list that is asked over and over again.
How do I get {cpu, memory, ...} usage in percentage? Or its modified
version: How do I plot nice graphs like virt-manager does?
It would be nice if we have an example to inspire people. And that's
what domtop should do. Yes, it could be written in different ways, but
I've chosen this one as I think it show explicitly what users need to
implement in order to imitate virt-manager's graphing.
Note: The usage is displayed from host perspective. That is, how much
host CPUs the domain is using. But it should be fairly simple to
switch do just guest CPU usage if needed.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
.gitignore | 1 +
Makefile.am | 2 +-
cfg.mk | 2 +-
configure.ac | 1 +
examples/domtop/Makefile.am | 27 +++
examples/domtop/domtop.c | 400 ++++++++++++++++++++++++++++++++++++++++++++
libvirt.spec.in | 2 +-
7 files changed, 432 insertions(+), 3 deletions(-)
create mode 100644 examples/domtop/Makefile.am
create mode 100644 examples/domtop/domtop.c
diff --git a/.gitignore b/.gitignore
index 2d4d401..90fee91 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,6 +75,7 @@
/examples/dominfo/info1
/examples/domsuspend/suspend
/examples/dommigrate/dommigrate
+/examples/domtop/domtop
/examples/hellolibvirt/hellolibvirt
/examples/openauth/openauth
/gnulib/lib/*
diff --git a/Makefile.am b/Makefile.am
index a374e1a..4aafe94 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,7 +24,7 @@ SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \
examples/dominfo examples/domsuspend examples/apparmor \
examples/xml/nwfilter examples/openauth examples/systemtap \
tools/wireshark examples/dommigrate \
- examples/lxcconvert
+ examples/lxcconvert examples/domtop
ACLOCAL_AMFLAGS = -I m4
diff --git a/cfg.mk b/cfg.mk
index c3d89a0..0559edd 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -1078,7 +1078,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/.*|examples/domsuspend/suspend)\.c$$
+ ^(src/util/.*|examples/dom.*/.*)\.c$$
exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$
diff --git a/configure.ac b/configure.ac
index 8001e24..f37c716 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2755,6 +2755,7 @@ AC_CONFIG_FILES([\
examples/domsuspend/Makefile \
examples/dominfo/Makefile \
examples/dommigrate/Makefile \
+ examples/domtop/Makefile \
examples/openauth/Makefile \
examples/hellolibvirt/Makefile \
examples/systemtap/Makefile \
diff --git a/examples/domtop/Makefile.am b/examples/domtop/Makefile.am
new file mode 100644
index 0000000..c5cb6c7
--- /dev/null
+++ b/examples/domtop/Makefile.am
@@ -0,0 +1,27 @@
+## Process this file with automake to produce Makefile.in
+
+## 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/>.
+
+INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+LDADDS = $(STATIC_BINARIES) $(WARN_CFLAGS) $(top_builddir)/src/libvirt.la \
+ $(COVERAGE_LDFLAGS)
+
+noinst_PROGRAMS=domtop
+
+domtop_SOURCES=domtop.c
+domtop_LDFLAGS=
+domtop_LDADD= $(LDADDS)
diff --git a/examples/domtop/domtop.c b/examples/domtop/domtop.c
new file mode 100644
index 0000000..6fb6cbe
--- /dev/null
+++ b/examples/domtop/domtop.c
@@ -0,0 +1,400 @@
+/*
+ * 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/>.
+ *
+ * Author: Michal Privoznik <mprivozn(a)redhat.com>
+ */
+
+#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>
+
+static bool debug;
+static bool run_top;
+
+#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\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 int
+parse_argv(int argc, char *argv[],
+ const char **uri,
+ const char **dom_name,
+ unsigned int *milliseconds)
+{
+ 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'},
+ {"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 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;
+ }
+ *milliseconds = val;
+ if (*milliseconds != 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 void
+print_cpu_usage(const char *dom_name,
+ 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, k;
+ 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;
+ 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=%llu then_params=%llu now=%llu then=%llu",
+ now_params[pos].value.ul, then_params[pos].value.ul, now, 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");
+ printf("CPU%zu: %.2lf", cpu + i, usage);
+ delim = true;
+ }
+
+ if (delim)
+ 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;
+ int nparams = 0, then_nparams = 0, now_nparams = 0;
+ virTypedParameterPtr then_params = NULL, now_params = NULL;
+ struct sigaction action_stop;
+
+ memset(&action_stop, 0, sizeof(action_stop));
+ action_stop.sa_handler = stop;
+
+ /* 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;
+ }
+
+ sigaction(SIGTERM, &action_stop, NULL);
+ sigaction(SIGINT, &action_stop, NULL);
+
+ 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(dom_name, 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:
+ if (max_id > 0) {
+ if (now_nparams > 0)
+ virTypedParamsFree(now_params, now_nparams * max_id);
+ if (then_nparams > 0)
+ virTypedParamsFree(then_params, then_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 */
+
+ if (parse_argv(argc, argv, &uri, &dom_name, &milliseconds) < 0)
+ goto cleanup;
+
+ 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;
+}
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 472fa4b..76e57aa 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1505,7 +1505,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 domsuspend hellolibvirt openauth xml/nwfilter systemtap dommigrate
+for i in object-events dominfo domsuspend hellolibvirt openauth xml/nwfilter systemtap dommigrate domtop
do
(cd examples/$i ; make clean ; rm -rf .deps .libs Makefile Makefile.in)
done
--
1.8.5.5
10 years, 11 months
[libvirt] [PATCH] doc: add domain to address of hostdev pci
by Hu Tao
libvirt supports pci domain already, so update the documentation.
Otherwise users who lookup the documentation for how to use hostdev may
miss the domain and encounter error when pass-through a pci device in a
domain other than 0.
Signed-off-by: Hu Tao <hutao(a)cn.fujitsu.com>
---
docs/formatdomain.html.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3c85fc5..4572feb 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2777,7 +2777,7 @@
<devices>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
- <address bus='0x06' slot='0x02' function='0x0'/>
+ <address domain='0x0000' bus='0x06' slot='0x02' function='0x0'/>
</source>
<boot order='1'/>
<rom bar='on' file='/etc/fake/boot.bin'/>
@@ -2891,7 +2891,7 @@
USB bus and device number the device appears at on the host.
The values of these attributes can be given in decimal, hexadecimal
(starting with 0x) or octal (starting with 0) form.
- For PCI devices the element carries 3 attributes allowing to designate
+ For PCI devices the element carries 4 attributes allowing to designate
the device as can be found with the <code>lspci</code> or
with <code>virsh
nodedev-list</code>. <a href="#elementsAddress">See above</a> for
--
1.9.3
10 years, 11 months
[libvirt] OVMF exposure in libvirt
by Michal Privoznik
Dear list,
there's been a lot of development in QEMU on this part. And I think it's
settled down enough long so I can start looking at it. So I'd like to
hear you opinion what's the best way to expose this in libvirt.
OVMF can bee looked at as a UEFI enablement in guest. Standard UEFI
consists of two parts:
a) the firmware binary image (RO)
b) UEFI variables flash (RW)
IIUC both of these are to be passed to qemu on the command line as:
-drive file=img_1,if=pflash,format=raw,readonly \
-drive file=img_2,if=pflash,format=raw
Subsequently, -bios parameter should be dropped. The idea of splitting
the UEFI into two files allows distros to update the UEFI firmware (FW
for short) without modifying guest written UEFI variables file (the
variables should have unified name so they should be transferable
between two versions of UEFI FW).
So my question is: how to expose this in the domain XML? We have the
<os/> element which handles the booting arguments. It can have <loader/>
(which would be great for the FW, wouldn't it?). But then we need to
invent a different element (say <vars/>) which would contain path the
the UEFI vars file. Moreover, the element would exclude other elements
like <boot/>, <bios/> or <smbios/>. So my proposal is:
<os>
<type>hvm</type>
<loader>/path/to/uefi.fw</loader>
<vars>/path/to/uefi.nvvarstore</vars>
</os>
Does this make any sense or am I just blabbing?
Michal
BTW OVMF stands for Open Virtual Machine Firmware.
10 years, 11 months
[libvirt] [libvirt-glib] gobject: Fix GEnum generation through glib-mkenums
by Christophe Fergeau
We were only passing libvirt-gobject-domain.h and
libvirt-gobject-connection.h through glib-mkenums, which causes it to
only generate GEnum information for enums found in these headers.
We want to do that for all enums defined in installed headers, so
passing all headers listed in libvirt_gobject_1_0_la_HEADERS is more
appropriate.
---
libvirt-gobject/Makefile.am | 4 ++--
libvirt-gobject/libvirt-gobject.sym | 5 +++++
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am
index 516c10f..7163c7d 100644
--- a/libvirt-gobject/Makefile.am
+++ b/libvirt-gobject/Makefile.am
@@ -93,7 +93,7 @@ libvirt_gobject_1_0_la_LDFLAGS = \
-Wl,--version-script=$(srcdir)/libvirt-gobject.sym \
-version-info $(LIBVIRT_GLIB_VERSION_INFO)
-libvirt-gobject-enums.c: libvirt-gobject-domain.h libvirt-gobject-connection.h
+libvirt-gobject-enums.c: $(libvirt_gobject_1_0_la_HEADERS)
$(AM_V_GEN)glib-mkenums \
--fhead "#include \"libvirt-gobject/libvirt-gobject.h\"\n\n" \
--vhead "static const G@Type@Value _@enum_name@_values[] = {" \
@@ -106,7 +106,7 @@ libvirt-gobject-enums.c: libvirt-gobject-domain.h libvirt-gobject-connection.h
--vtail " return type;\n}\n\n" \
$^ | sed -e 's/g_vir/gvir/g' > $@
-libvirt-gobject-enums.h: libvirt-gobject-domain.h libvirt-gobject-connection.h
+libvirt-gobject-enums.h: $(libvirt_gobject_1_0_la_HEADERS)
$(AM_V_GEN)glib-mkenums --fhead "#ifndef __LIBVIRT_GOBJECT_ENUMS_H__\n" \
--fhead "#define __LIBVIRT_GOBJECT_ENUMS_H__\n\n" \
--fhead "G_BEGIN_DECLS\n\n" \
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index b781cc6..4e856e7 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -237,6 +237,11 @@ LIBVIRT_GOBJECT_0.1.5 {
LIBVIRT_GOBJECT_0.1.9 {
global:
gvir_domain_snapshot_delete;
+ gvir_domain_snapshot_delete_flags_get_type;
+ gvir_storage_pool_state_get_type;
+ gvir_storage_vol_resize_flags_get_type;
+ gvir_storage_vol_type_get_type;
+ gvir_stream_io_condition_get_type;
} LIBVIRT_GOBJECT_0.1.5;
# .... define new API here using predicted next version number ....
--
1.9.3
10 years, 11 months
[libvirt] [PATCH v3 00/16] Support for per-guest-node binding
by Martin Kletzander
v3 of https://www.redhat.com/archives/libvir-list/2014-July/msg00372.html
v3:
- Michal's suggestions worked in
- rebased on current master
Martin Kletzander (16):
qemu: purely a code movement
qemu: remove useless error check
conf: purely a code movement
conf, schema: add 'id' field for cells
numatune: create new module for numatune
numatune: unify numatune struct and enum names
numatune: Encapsulate numatune configuration in order to unify results
conf, schema: add support for memnode elements
numatune: add support for per-node memory bindings in private APIs
qemu: allow qmp probing for cmdline options without params
qemu: memory-backend-ram capability probing
qemu: newer -numa parameter capability probing
qemu: enable disjoint numa cpu ranges
qemu: pass numa node binding preferences to qemu
qemu: split out cpuset.mems setting
qemu: leave restricting cpuset.mems after initialization
docs/formatdomain.html.in | 32 +-
docs/schemas/domaincommon.rng | 22 +
po/POTFILES.in | 1 +
src/Makefile.am | 3 +-
src/conf/cpu_conf.c | 41 +-
src/conf/cpu_conf.h | 3 +-
src/conf/domain_conf.c | 203 ++-----
src/conf/domain_conf.h | 10 +-
src/conf/numatune_conf.c | 595 +++++++++++++++++++++
src/conf/numatune_conf.h | 108 ++++
src/libvirt_private.syms | 24 +-
src/lxc/lxc_cgroup.c | 20 +-
src/lxc/lxc_controller.c | 5 +-
src/lxc/lxc_native.c | 15 +-
src/parallels/parallels_driver.c | 7 +-
src/qemu/qemu_capabilities.c | 16 +-
src/qemu/qemu_capabilities.h | 2 +
src/qemu/qemu_cgroup.c | 52 +-
src/qemu/qemu_cgroup.h | 4 +-
src/qemu/qemu_command.c | 98 +++-
src/qemu/qemu_driver.c | 84 ++-
src/qemu/qemu_monitor.c | 6 +-
src/qemu/qemu_monitor.h | 3 +-
src/qemu/qemu_monitor_json.c | 8 +-
src/qemu/qemu_monitor_json.h | 3 +-
src/qemu/qemu_process.c | 12 +-
src/util/virnuma.c | 61 +--
src/util/virnuma.h | 28 +-
tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 +
tests/qemucapabilitiesdata/caps_1.6.50-1.replies | 5 +
tests/qemumonitorjsontest.c | 20 +-
.../qemuxml2argv-cpu-numa-disjoint.args | 6 +
.../qemuxml2argv-cpu-numa-disjoint.xml | 28 +
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml | 6 +-
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml | 6 +-
tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml | 25 +
.../qemuxml2argv-numatune-auto-prefer.xml | 29 +
.../qemuxml2argv-numatune-memnode-no-memory.args | 8 +
.../qemuxml2argv-numatune-memnode-no-memory.xml | 30 ++
.../qemuxml2argv-numatune-memnode-nocpu.xml | 25 +
.../qemuxml2argv-numatune-memnode.args | 11 +
.../qemuxml2argv-numatune-memnode.xml | 33 ++
.../qemuxml2argv-numatune-memnodes-problematic.xml | 31 ++
tests/qemuxml2argvtest.c | 12 +
.../qemuxml2xmlout-cpu-numa1.xml | 28 +
.../qemuxml2xmlout-cpu-numa2.xml | 28 +
.../qemuxml2xmlout-numatune-auto-prefer.xml | 29 +
.../qemuxml2xmlout-numatune-memnode.xml | 33 ++
tests/qemuxml2xmltest.c | 8 +
49 files changed, 1479 insertions(+), 389 deletions(-)
create mode 100644 src/conf/numatune_conf.c
create mode 100644 src/conf/numatune_conf.h
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-nocpu.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnodes-problematic.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-numatune-auto-prefer.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-numatune-memnode.xml
--
2.0.0
10 years, 11 months
[libvirt] [PATCH] qemuConnectGetDomainCapabilities: Use wiser defaults
by Michal Privoznik
Up to now, users have to pass two arguments at least: domain virt type
('qemu' vs 'kvm') and one of emulatorbin or architecture. This is not
much user friendly. Nowadays users mostly use KVM and share the host
architecture with the guest. So now, the API (and subsequently virsh
command) can be called with all NULLs (without any arguments).
Before this patch:
# virsh domcapabilities
error: failed to get emulator capabilities
error: virttype_str in qemuConnectGetDomainCapabilities must not be NULL
# virsh domcapabilities kvm
error: failed to get emulator capabilities
error: invalid argument: at least one of emulatorbin or architecture fields must be present
After:
# virsh domcapabilities
<domainCapabilities>
<path>/usr/bin/qemu-system-x86_64</path>
<domain>kvm</domain>
<machine>pc-i440fx-2.1</machine>
<arch>x86_64</arch>
<vcpu max='255'/>
</domainCapabilities>
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/qemu/qemu_driver.c | 24 ++++++------------------
1 file changed, 6 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 33541d3..7d99435 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16849,17 +16849,17 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
char *ret = NULL;
virQEMUDriverPtr driver = conn->privateData;
virQEMUCapsPtr qemuCaps = NULL;
- int virttype; /* virDomainVirtType */
+ int virttype = VIR_DOMAIN_VIRT_KVM; /* virDomainVirtType */
virDomainCapsPtr domCaps = NULL;
- int arch = VIR_ARCH_NONE; /* virArch */
+ int arch = virArchFromHost(); /* virArch */
virCheckFlags(0, ret);
- virCheckNonNullArgReturn(virttype_str, ret);
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
return ret;
- if ((virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
+ if (virttype_str &&
+ (virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
virReportError(VIR_ERR_INVALID_ARG,
_("unknown virttype: %s"),
virttype_str);
@@ -16882,9 +16882,6 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
arch_from_caps = virQEMUCapsGetArch(qemuCaps);
- if (arch == VIR_ARCH_NONE)
- arch = arch_from_caps;
-
if (arch_from_caps != arch) {
virReportError(VIR_ERR_INVALID_ARG,
_("architecture from emulator '%s' doesn't "
@@ -16893,21 +16890,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
virArchToString(arch));
goto cleanup;
}
- } else if (arch_str) {
+ } else {
if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache,
arch)))
goto cleanup;
- if (!emulatorbin)
- emulatorbin = virQEMUCapsGetBinary(qemuCaps);
- /* Deliberately not checking if provided @emulatorbin matches @arch,
- * since if @emulatorbin was specified the match has been checked a few
- * lines above. */
- } else {
- virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("at least one of emulatorbin or "
- "architecture fields must be present"));
- goto cleanup;
+ emulatorbin = virQEMUCapsGetBinary(qemuCaps);
}
if (machine) {
--
1.8.5.5
10 years, 11 months
[libvirt] [PATCH] spec: Consolidate with_qemu* definitions
by Jiri Denemark
Decisions whether qemu driver and libvirt-daemon-{qemu,kvm} packages
should be built on various OS/arch combinations were scattered around
the spec file. Let's make it easier to see where qemu driver is going to
be built.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
libvirt.spec.in | 52 +++++++++++++++++++++++++---------------------------
1 file changed, 25 insertions(+), 27 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 9c7b241..472fa4b 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -54,15 +54,27 @@
%define with_vbox 0%{!?_without_vbox:%{server_drivers}}
%define with_qemu_tcg %{with_qemu}
-# Change if we ever provide qemu-kvm binaries on non-x86 hosts
-%if 0%{?fedora} >= 18
+
+%define qemu_kvm_arches %{ix86} x86_64
+
+%if 0%{?fedora}
+ %if 0%{?fedora} < 16
+ # Fedora doesn't have any QEMU on ppc64 until FC16 - only ppc
+ %ifarch ppc64
+ %define with_qemu_tcg 0
+ %endif
+ %endif
+ %if 0%{?fedora} >= 18
+ %define qemu_kvm_arches %{ix86} x86_64 ppc64 s390x
+ %endif
%if 0%{?fedora} >= 20
- %define qemu_kvm_arches %{ix86} x86_64 ppc64 s390x %{arm}
- %else
- %define qemu_kvm_arches %{ix86} x86_64 ppc64 s390x
+ %define qemu_kvm_arches %{ix86} x86_64 ppc64 s390x %{arm}
%endif
-%else
- %define qemu_kvm_arches %{ix86} x86_64
+%endif
+
+%if 0%{?rhel}
+ %define with_qemu_tcg 0
+ %define qemu_kvm_arches x86_64
%endif
%ifarch %{qemu_kvm_arches}
@@ -71,6 +83,10 @@
%define with_qemu_kvm 0
%endif
+%if ! %{with_qemu_tcg} && ! %{with_qemu_kvm}
+ %define with_qemu 0
+%endif
+
# Then the hypervisor drivers that run outside libvirtd, in libvirt.so
%define with_openvz 0%{!?_without_openvz:1}
%define with_vmware 0%{!?_without_vmware:1}
@@ -191,34 +207,16 @@
%define with_firewalld 1
%endif
-# RHEL-5 has restricted QEMU to x86_64 only and is too old for LXC
+# RHEL-5 is too old for LXC
%if 0%{?rhel} == 5
- %define with_qemu_tcg 0
- %ifnarch x86_64
- %define with_qemu 0
- %define with_qemu_kvm 0
- %endif
%define with_lxc 0
%endif
-# RHEL-6 has restricted QEMU to x86_64 only, stopped including Xen
-# on all archs. Other archs all have LXC available though
+# RHEL-6 stopped including Xen on all archs.
%if 0%{?rhel} >= 6
- %define with_qemu_tcg 0
- %ifnarch x86_64
- %define with_qemu 0
- %define with_qemu_kvm 0
- %endif
%define with_xen 0
%endif
-# Fedora doesn't have any QEMU on ppc64 until FC16 - only ppc
-%if 0%{?fedora} && 0%{?fedora} < 16
- %ifarch ppc64
- %define with_qemu 0
- %endif
-%endif
-
# Fedora doesn't have new enough Xen for libxl until F18
%if 0%{?fedora} && 0%{?fedora} < 18
%define with_libxl 0
--
2.0.0
10 years, 11 months
[libvirt] [PATCH 00/29] vbox: Rewrite several APIs.
by Taowei
Put exactly one API into one patch.
Add a test case to test with vboxUniformedAPI.
Taowei (29):
vbox: Begin to rewrite, vboxConnectOpen
vbox: Add test case for vboxUniformedAPI
vbox: Rewrite vboxConnectClose
vbox: Rewrite vboxDomainSave
vbox: Rewrite vboxConnectGetVersion
vbox: Rewrite vboxConnectGetHostname
vbox: Rewrite vboxConnectIsSecure
vbox: Rewrite vboxConnectIsEncrypted
vbox: Rewrite vboxConnectIsAlive
vbox: Rewrite vboxConnectGetMaxVcpus
vbox: Rewrite vboxConnectGetCapabilities
vbox: Rewrite vboxConnectListDomains
vbox: Rewrite vboxConnectNumOfDomains
vbox: Rewrite vboxDomainLookupById
vbox: Rewrite vboxDomainLookupByUUId
vbox: Rewrite vboxDomainUndefineFlags
vbox: Rewrite vboxDomainDefineXML
vbox: Rewrite vboxDomainCreateWithFlags
vbox: Rewrite vboxDomainCreate
vbox: Rewrite vboxDomainCreateXML
vbox: Rewrite vboxDomainLookupByName
vbox: Rewrite vboxDomainIsActive
vbox: Rewrite vboxDomainIsPersistent
vbox: Rewrite vboxDomainIsUpdated
vbox: Rewrite vboxDomainSuspend
vbox: Rewrite vboxDomainResume
vbox: Rewrite vboxDomainShutdownFlags
vbox: Rewrite vboxDomainShutdown
vbox: Rewrite vboxDomainReboot
po/POTFILES.in | 1 +
src/Makefile.am | 4 +-
src/vbox/vbox_common.c | 2547 ++++++++++++++++++++++++++
src/vbox/vbox_common.h | 261 +++
src/vbox/vbox_driver.c | 23 +-
src/vbox/vbox_tmpl.c | 4041 ++++++++++++++++-------------------------
src/vbox/vbox_uniformed_api.h | 461 +++++
tests/Makefile.am | 9 +-
tests/vboxuniformedapitest.c | 98 +
9 files changed, 4933 insertions(+), 2512 deletions(-)
create mode 100644 src/vbox/vbox_common.c
create mode 100644 src/vbox/vbox_common.h
create mode 100644 src/vbox/vbox_uniformed_api.h
create mode 100644 tests/vboxuniformedapitest.c
--
1.7.9.5
10 years, 11 months