[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, 4 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, 4 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, 4 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, 4 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, 4 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, 4 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, 4 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, 4 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, 4 months
[libvirt] [PATCH] support vhost-scsi controller
by Zhang Min
libvirt support vhost-scsi controller. The way to config
the vhost-scsi controller is edit the xml file, Format is
as follows:
<controller type='scsi' index='0' model='vhost-scsi'>
<source wwpn='naa.6001405f5e3acbba' event_idx='on'/>
</controller>
the tag of "wwpn" is necessary, the 'model' must be 'vhost-scsi'
'event_idx' is optional.
Signed-off-by: Zhang Min <rudy.zhangmin(a)huawei.com>
---
src/conf/domain_conf.c | 64 +++++++++++++++++++++++++++++++++++++++--
src/conf/domain_conf.h | 10 ++++++
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 21 ++++++++++++-
src/vmx/vmx.c | 3 +-
6 files changed, 94 insertions(+), 7 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 54925ba..e42ede7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -306,7 +306,8 @@ VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAS
"vmpvscsi",
"ibmvscsi",
"virtio-scsi",
- "lsisas1078");
+ "lsisas1078",
+ "vhost-scsi");
VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST,
"piix3-uhci",
@@ -1290,6 +1291,10 @@ void virDomainControllerDefFree(virDomainControllerDefPtr def)
if (!def)
return;
+ if (def->vhostscsi.wwpn)
+ VIR_FREE(def->vhostscsi.wwpn);
+ memset(&def->vhostscsi, 0, sizeof(def->vhostscsi));
+
virDomainDeviceInfoClear(&def->info);
VIR_FREE(def);
@@ -6051,6 +6056,9 @@ virDomainControllerDefParseXML(xmlNodePtr node,
char *max_sectors = NULL;
xmlNodePtr saved = ctxt->node;
int rc;
+ char *wwpn = NULL;
+ char *event_idx = NULL;
+ int event_idx_num = 0;
ctxt->node = node;
@@ -6087,13 +6095,42 @@ virDomainControllerDefParseXML(xmlNodePtr node,
def->model = -1;
}
+ def->vhostscsi.wwpn = NULL;
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
if (xmlStrEqual(cur->name, BAD_CAST "driver"))
queues = virXMLPropString(cur, "queues");
- cmd_per_lun = virXMLPropString(cur, "cmd_per_lun");
- max_sectors = virXMLPropString(cur, "max_sectors");
+ else if(xmlStrEqual(cur->name, BAD_CAST "source")) {
+ switch (def->model) {
+ case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI:
+ wwpn = virXMLPropString(cur, "wwpn");
+ if (wwpn && !STREQ(wwpn,"")) {
+ def->vhostscsi.wwpn = wwpn;
+ wwpn = NULL;
+ } else {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("vhost-scsi:wwpn can't be null"));
+ goto error;
+ }
+
+ event_idx = virXMLPropString(cur, "event_idx");
+ if (event_idx) {
+ if ((event_idx_num = virDomainVirtioEventIdxTypeFromString(event_idx)) <= 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown vhost-scsi event_idx mode '%s'"),
+ event_idx);
+ goto error;
+ }
+ def->vhostscsi.event_idx = event_idx_num;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ cmd_per_lun = virXMLPropString(cur, "cmd_per_lun");
+ max_sectors = virXMLPropString(cur, "max_sectors");
}
cur = cur->next;
}
@@ -6216,6 +6253,12 @@ virDomainControllerDefParseXML(xmlNodePtr node,
goto error;
}
+ if (def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI &&
+ def->vhostscsi.wwpn == NULL) {
+ virReportError(VIR_ERR_XML_ERROR,_("vhost-scsi:wwpn can't be null"));
+ goto error;
+ }
+
cleanup:
ctxt->node = saved;
VIR_FREE(type);
@@ -6224,6 +6267,8 @@ virDomainControllerDefParseXML(xmlNodePtr node,
VIR_FREE(queues);
VIR_FREE(cmd_per_lun);
VIR_FREE(max_sectors);
+ VIR_FREE(wwpn);
+ VIR_FREE(event_idx);
return def;
@@ -15300,10 +15345,21 @@ virDomainControllerDefFormat(virBufferPtr buf,
break;
}
- if (def->queues || def->cmd_per_lun || def->max_sectors ||
+ if (def->queues || def->cmd_per_lun || def->max_sectors || def->vhostscsi.wwpn
virDomainDeviceInfoIsSet(&def->info, flags) || pcihole64) {
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
+
+ if (def->vhostscsi.wwpn) {
+ virBufferAsprintf(buf, " <source wwpn='%s'", def->vhostscsi.wwpn);
+
+ if (def->vhostscsi.event_idx) {
+ virBufferAsprintf(buf, " event_idx='%s'",
+ virDomainVirtioEventIdxTypeToString(def->vhostscsi.event_idx));
+ }
+ virBufferAddLit(buf, "/>\n");
+ }
+
if (def->queues)
virBufferAsprintf(buf, "<driver queues='%u'/>\n", def->queues);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a00e30a..7b3cfd8 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -679,6 +679,7 @@ typedef enum {
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI,
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI,
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSISAS1078,
+ VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI,
VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST
} virDomainControllerModelSCSI;
@@ -713,6 +714,14 @@ struct _virDomainPCIControllerOpts {
unsigned long pcihole64size;
};
+/* Stores the vhost-scsi controller configuration */
+typedef struct _virDomainControllerVhostDef virDomainControllerVhostDef;
+typedef virDomainControllerVhostDef *virDomainControllerVhostDefPtr;
+struct _virDomainControllerVhostDef {
+ char *wwpn;
+ int event_idx;
+};
+
/* Stores the virtual disk controller configuration */
struct _virDomainControllerDef {
int type;
@@ -721,6 +730,7 @@ struct _virDomainControllerDef {
unsigned int queues;
unsigned int cmd_per_lun;
unsigned int max_sectors;
+ virDomainControllerVhostDef vhostscsi;
union {
virDomainVirtioSerialOpts vioserial;
virDomainPCIControllerOpts pciopts;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 40ebf29..bf124b7 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -258,6 +258,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"host-pci-multidomain",
"msg-timestamp",
"active-commit",
+ "vhost-scsi-pci",
);
@@ -1445,6 +1446,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "virtio-scsi-pci", QEMU_CAPS_VIRTIO_SCSI },
{ "virtio-scsi-s390", QEMU_CAPS_VIRTIO_SCSI },
{ "virtio-scsi-ccw", QEMU_CAPS_VIRTIO_SCSI },
+ { "vhost-scsi-pci", QEMU_CAPS_VHOST_SCSI },
{ "megasas", QEMU_CAPS_SCSI_MEGASAS },
{ "spicevmc", QEMU_CAPS_DEVICE_SPICEVMC },
{ "qxl-vga", QEMU_CAPS_DEVICE_QXL_VGA },
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 0ea8de8..9eb18f4 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -208,6 +208,7 @@ typedef enum {
QEMU_CAPS_HOST_PCI_MULTIDOMAIN = 166, /* support domain > 0 in host pci address */
QEMU_CAPS_MSG_TIMESTAMP = 167, /* -msg timestamp */
QEMU_CAPS_ACTIVE_COMMIT = 168, /* block-commit works without 'top' */
+ QEMU_CAPS_VHOST_SCSI = 153, /* -device vhost-scsi-pci */
QEMU_CAPS_LAST, /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index fb64cda..02edad2 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -701,6 +701,14 @@ qemuSetSCSIControllerModel(virDomainDefPtr def,
return -1;
}
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI:
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VHOST_SCSI)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("This QEMU doesn't support "
+ "vhost scsi controller"));
+ return -1;
+ }
+ break;
case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI:
/*TODO: need checking work here if necessary */
break;
@@ -4119,8 +4127,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
virBuffer buf = VIR_BUFFER_INITIALIZER;
int model;
- if (!(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
- def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI)) {
+ if (!((def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) &&
+ (def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI ||
+ def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI))) {
if (def->queues) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("'queues' is only supported by virtio-scsi controller"));
@@ -4157,6 +4166,14 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
else
virBufferAddLit(&buf, "virtio-scsi-pci");
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VHOST_SCSI:
+ virBufferAddLit(&buf, "vhost-scsi-pci");
+ virBufferAsprintf(&buf, ",wwpn=%s", def->vhostscsi.wwpn);
+ if (def->vhostscsi.event_idx) {
+ virBufferAsprintf(&buf, ",event_idx=%s",
+ virDomainVirtioEventIdxTypeToString(def->vhostscsi.event_idx));
+ }
+ break;
case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC:
virBufferAddLit(&buf, "lsi");
break;
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index cd6c51e..ace6ccd 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -517,7 +517,8 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
"pvscsi",
"UNUSED ibmvscsi",
"UNUSED virtio-scsi",
- "UNUSED lsisas1078");
+ "UNUSED lsisas1078",
+ "UNUSED vhost-scsi");
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
--
zhang min
10 years, 4 months