Accepting request 292894 from Virtualization
Automatic submission by obs-autosubmit OBS-URL: https://build.opensuse.org/request/show/292894 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/xen?expand=0&rev=202
This commit is contained in:
commit
f7e27d5f03
159
5124efbe-add-qxl-support.patch
Normal file
159
5124efbe-add-qxl-support.patch
Normal file
@ -0,0 +1,159 @@
|
||||
Usage:
|
||||
vga="qxl"
|
||||
|
||||
Qxl vga support many resolutions that not supported by stdvga,
|
||||
mainly the 16:9 ones and other high up to 2560x1600.
|
||||
With QXL you can get improved performance and smooth video also
|
||||
with high resolutions and high quality.
|
||||
Require their drivers installed in the domU and spice used
|
||||
otherwise act as a simple stdvga.
|
||||
|
||||
Signed-off-by: Fabio Fantoni <fabio.fantoni@xxxxxxx>
|
||||
Signed-off-by: Zhou Peng <zpengxen@xxxxxxxxx>
|
||||
Acked-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
|
||||
Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
|
||||
Acked-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>
|
||||
|
||||
---
|
||||
|
||||
Changes in v16:
|
||||
- refresh
|
||||
- improved commit description
|
||||
|
||||
Changes in v15:
|
||||
- refresh
|
||||
- small code improvements in libxl_dm.c
|
||||
|
||||
Changes in v14:
|
||||
- refresh
|
||||
- update qemu parameters (from -vga to -device)
|
||||
|
||||
NOTES:
|
||||
Works correctly with windows domUs, tested on windows 7 64 bit
|
||||
with qxl driver from spice guest tools 0.74.
|
||||
I tested some resolution not supported by stdvga (1366x768, 1600x900
|
||||
and 1920x1080) with 32 bit color and all works good equal to kvm.
|
||||
For now not works on linux domUs when xorg have 100% cpu and black
|
||||
screen with qxl driver installed.
|
||||
Seems needed other changes/fixes on xen and/or xorg/qxl driver side
|
||||
before have it full working with linux domUs.
|
||||
---
|
||||
docs/man/xl.cfg.pod.5 | 10 +++++++++-
|
||||
tools/libxl/libxl_create.c | 13 +++++++++++++
|
||||
tools/libxl/libxl_dm.c | 8 ++++++++
|
||||
tools/libxl/libxl_types.idl | 1 +
|
||||
tools/libxl/xl_cmdimpl.c | 2 ++
|
||||
5 files changed, 33 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: xen-4.5.0-testing/docs/man/xl.cfg.pod.5
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/docs/man/xl.cfg.pod.5
|
||||
+++ xen-4.5.0-testing/docs/man/xl.cfg.pod.5
|
||||
@@ -1292,6 +1292,9 @@ qemu-xen-traditional device-model, the a
|
||||
which is sufficient for 1024x768 at 32 bpp. For the upstream qemu-xen
|
||||
device-model, the default and minimum is 8 MB.
|
||||
|
||||
+For B<qxl> vga, the default is both default and minimal 128MB.
|
||||
+If B<videoram> is set less than 128MB, an error will be triggered.
|
||||
+
|
||||
=item B<stdvga=BOOLEAN>
|
||||
|
||||
Select a standard VGA card with VBE (VESA BIOS Extensions) as the
|
||||
@@ -1303,9 +1306,14 @@ This option is deprecated, use vga="stdv
|
||||
|
||||
=item B<vga="STRING">
|
||||
|
||||
-Selects the emulated video card (none|stdvga|cirrus).
|
||||
+Selects the emulated video card (none|stdvga|cirrus|qxl).
|
||||
The default is cirrus.
|
||||
|
||||
+In general, QXL should work with the Spice remote display protocol
|
||||
+for acceleration, and QXL driver is necessary in guest in this case.
|
||||
+QXL can also work with the VNC protocol, but it will be like a standard
|
||||
+VGA without acceleration.
|
||||
+
|
||||
=item B<vnc=BOOLEAN>
|
||||
|
||||
Allow access to the display via the VNC protocol. This enables the
|
||||
Index: xen-4.5.0-testing/tools/libxl/libxl_create.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/libxl_create.c
|
||||
+++ xen-4.5.0-testing/tools/libxl/libxl_create.c
|
||||
@@ -240,6 +240,10 @@ int libxl__domain_build_info_setdefault(
|
||||
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
|
||||
b_info->video_memkb = 0;
|
||||
break;
|
||||
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
|
||||
+ LOG(ERROR,"qemu upstream required for qxl vga");
|
||||
+ return ERROR_INVAL;
|
||||
+ break;
|
||||
case LIBXL_VGA_INTERFACE_TYPE_STD:
|
||||
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
|
||||
b_info->video_memkb = 8 * 1024;
|
||||
@@ -264,6 +268,15 @@ int libxl__domain_build_info_setdefault(
|
||||
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
|
||||
b_info->video_memkb = 0;
|
||||
break;
|
||||
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
|
||||
+ if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT) {
|
||||
+ b_info->video_memkb = (128 * 1024);
|
||||
+ } else if (b_info->video_memkb < (128 * 1024)) {
|
||||
+ LOG(ERROR,
|
||||
+ "128 Mib videoram is the minimum for qxl default");
|
||||
+ return ERROR_INVAL;
|
||||
+ }
|
||||
+ break;
|
||||
case LIBXL_VGA_INTERFACE_TYPE_STD:
|
||||
if (b_info->video_memkb == LIBXL_MEMKB_DEFAULT)
|
||||
b_info->video_memkb = 16 * 1024;
|
||||
Index: xen-4.5.0-testing/tools/libxl/libxl_dm.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/libxl_dm.c
|
||||
+++ xen-4.5.0-testing/tools/libxl/libxl_dm.c
|
||||
@@ -244,6 +244,8 @@ static char ** libxl__build_device_model
|
||||
case LIBXL_VGA_INTERFACE_TYPE_NONE:
|
||||
flexarray_append_pair(dm_args, "-vga", "none");
|
||||
break;
|
||||
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (b_info->u.hvm.boot) {
|
||||
@@ -590,6 +592,12 @@ static char ** libxl__build_device_model
|
||||
break;
|
||||
case LIBXL_VGA_INTERFACE_TYPE_NONE:
|
||||
break;
|
||||
+ case LIBXL_VGA_INTERFACE_TYPE_QXL:
|
||||
+ /* QXL have 2 ram regions, ram and vram */
|
||||
+ flexarray_append_pair(dm_args, "-device",
|
||||
+ GCSPRINTF("qxl-vga,vram_size_mb=%"PRIu64",ram_size_mb=%"PRIu64,
|
||||
+ (b_info->video_memkb/2/1024), (b_info->video_memkb/2/1024) ) );
|
||||
+ break;
|
||||
}
|
||||
|
||||
if (b_info->u.hvm.boot) {
|
||||
Index: xen-4.5.0-testing/tools/libxl/libxl_types.idl
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/libxl_types.idl
|
||||
+++ xen-4.5.0-testing/tools/libxl/libxl_types.idl
|
||||
@@ -181,6 +181,7 @@ libxl_vga_interface_type = Enumeration("
|
||||
(1, "CIRRUS"),
|
||||
(2, "STD"),
|
||||
(3, "NONE"),
|
||||
+ (4, "QXL"),
|
||||
], init_val = "LIBXL_VGA_INTERFACE_TYPE_CIRRUS")
|
||||
|
||||
libxl_vendor_device = Enumeration("vendor_device", [
|
||||
Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/xl_cmdimpl.c
|
||||
+++ xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
@@ -1910,6 +1910,8 @@ skip_vfb:
|
||||
b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
|
||||
} else if (!strcmp(buf, "none")) {
|
||||
b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_NONE;
|
||||
+ } else if (!strcmp(buf, "qxl")) {
|
||||
+ b_info->u.hvm.vga.kind = LIBXL_VGA_INTERFACE_TYPE_QXL;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown vga \"%s\" specified\n", buf);
|
||||
exit(1);
|
@ -503,7 +503,7 @@ Index: xen-4.5.0-testing/tools/libxl/libxl_create.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/libxl_create.c
|
||||
+++ xen-4.5.0-testing/tools/libxl/libxl_create.c
|
||||
@@ -1128,6 +1128,7 @@ static void domcreate_rebuild_done(libxl
|
||||
@@ -1141,6 +1141,7 @@ static void domcreate_rebuild_done(libxl
|
||||
libxl__multidev_begin(ao, &dcs->multidev);
|
||||
dcs->multidev.callback = domcreate_launch_dm;
|
||||
libxl__add_disks(egc, ao, domid, d_config, &dcs->multidev);
|
||||
@ -594,7 +594,7 @@ Index: xen-4.5.0-testing/tools/libxl/libxl_types.idl
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/libxl_types.idl
|
||||
+++ xen-4.5.0-testing/tools/libxl/libxl_types.idl
|
||||
@@ -539,6 +539,26 @@ libxl_device_channel = Struct("device_ch
|
||||
@@ -540,6 +540,26 @@ libxl_device_channel = Struct("device_ch
|
||||
])),
|
||||
])
|
||||
|
||||
@ -621,7 +621,7 @@ Index: xen-4.5.0-testing/tools/libxl/libxl_types.idl
|
||||
libxl_domain_config = Struct("domain_config", [
|
||||
("c_info", libxl_domain_create_info),
|
||||
("b_info", libxl_domain_build_info),
|
||||
@@ -552,6 +572,8 @@ libxl_domain_config = Struct("domain_con
|
||||
@@ -553,6 +573,8 @@ libxl_domain_config = Struct("domain_con
|
||||
# a channel manifests as a console with a name,
|
||||
# see docs/misc/channels.txt
|
||||
("channels", Array(libxl_device_channel, "num_channels")),
|
||||
@ -630,7 +630,7 @@ Index: xen-4.5.0-testing/tools/libxl/libxl_types.idl
|
||||
|
||||
("on_poweroff", libxl_action_on_shutdown),
|
||||
("on_reboot", libxl_action_on_shutdown),
|
||||
@@ -594,6 +616,28 @@ libxl_vtpminfo = Struct("vtpminfo", [
|
||||
@@ -595,6 +617,28 @@ libxl_vtpminfo = Struct("vtpminfo", [
|
||||
("uuid", libxl_uuid),
|
||||
], dir=DIR_OUT)
|
||||
|
||||
@ -904,7 +904,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
if (!xlu_cfg_get_list(config, "vtpm", &vtpms, 0, 0)) {
|
||||
d_config->num_vtpms = 0;
|
||||
d_config->vtpms = NULL;
|
||||
@@ -6490,6 +6668,256 @@ int main_blockdetach(int argc, char **ar
|
||||
@@ -6492,6 +6670,256 @@ int main_blockdetach(int argc, char **ar
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -387,7 +387,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/xl_cmdimpl.c
|
||||
+++ xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
@@ -3878,6 +3878,8 @@ static void migrate_do_preamble(int send
|
||||
@@ -3880,6 +3880,8 @@ static void migrate_do_preamble(int send
|
||||
}
|
||||
|
||||
static void migrate_domain(uint32_t domid, const char *rune, int debug,
|
||||
@ -396,7 +396,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
const char *override_config_file)
|
||||
{
|
||||
pid_t child = -1;
|
||||
@@ -3886,7 +3888,13 @@ static void migrate_domain(uint32_t domi
|
||||
@@ -3888,7 +3890,13 @@ static void migrate_domain(uint32_t domi
|
||||
char *away_domname;
|
||||
char rc_buf;
|
||||
uint8_t *config_data;
|
||||
@ -411,7 +411,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
|
||||
save_domain_core_begin(domid, override_config_file,
|
||||
&config_data, &config_len);
|
||||
@@ -3905,10 +3913,13 @@ static void migrate_domain(uint32_t domi
|
||||
@@ -3907,10 +3915,13 @@ static void migrate_domain(uint32_t domi
|
||||
xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0);
|
||||
|
||||
if (debug)
|
||||
@ -428,7 +428,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
" (rc=%d)\n", rc);
|
||||
if (rc == ERROR_GUEST_TIMEDOUT)
|
||||
goto failed_suspend;
|
||||
@@ -4295,13 +4306,18 @@ int main_migrate(int argc, char **argv)
|
||||
@@ -4297,13 +4308,18 @@ int main_migrate(int argc, char **argv)
|
||||
char *rune = NULL;
|
||||
char *host;
|
||||
int opt, daemonize = 1, monitor = 1, debug = 0;
|
||||
@ -448,7 +448,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
case 'C':
|
||||
config_filename = optarg;
|
||||
break;
|
||||
@@ -4318,6 +4334,18 @@ int main_migrate(int argc, char **argv)
|
||||
@@ -4320,6 +4336,18 @@ int main_migrate(int argc, char **argv)
|
||||
case 0x100:
|
||||
debug = 1;
|
||||
break;
|
||||
@ -467,7 +467,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
}
|
||||
|
||||
domid = find_domain(argv[optind]);
|
||||
@@ -4348,7 +4376,8 @@ int main_migrate(int argc, char **argv)
|
||||
@@ -4350,7 +4378,8 @@ int main_migrate(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
12
qemu-xen-enable-spice-support.patch
Normal file
12
qemu-xen-enable-spice-support.patch
Normal file
@ -0,0 +1,12 @@
|
||||
Index: xen-4.5.0-testing/tools/Makefile
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/Makefile
|
||||
+++ xen-4.5.0-testing/tools/Makefile
|
||||
@@ -222,6 +222,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-fi
|
||||
--datadir=$(SHAREDIR)/qemu-xen \
|
||||
--localstatedir=$(localstatedir) \
|
||||
--disable-kvm \
|
||||
+ $(QEMU_XEN_ENABLE_SPICE) \
|
||||
--disable-docs \
|
||||
--disable-guest-agent \
|
||||
--python=$(PYTHON) \
|
14
xen.changes
14
xen.changes
@ -1,3 +1,17 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Mar 16 10:14:15 MDT 2015 - carnold@suse.com
|
||||
|
||||
- Enable spice support in qemu for x86_64
|
||||
5124efbe-add-qxl-support.patch
|
||||
qemu-xen-enable-spice-support.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Mar 11 13:15:07 MDT 2015 - carnold@suse.com
|
||||
|
||||
- bnc#921842 - Xentop doesn't display disk statistics for VMs using
|
||||
qdisks
|
||||
xentop-add-support-for-qdisk.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Feb 24 16:22:45 UTC 2015 - meissner@suse.com
|
||||
|
||||
|
20
xen.spec
20
xen.spec
@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package xen
|
||||
#
|
||||
# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||
# Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@ -98,6 +98,13 @@ BuildRequires: libpixman-1-0-devel
|
||||
BuildRequires: libuuid-devel
|
||||
BuildRequires: libxml2-devel
|
||||
BuildRequires: libyajl-devel
|
||||
%ifarch x86_64
|
||||
%if 0%{?suse_version} > 1230
|
||||
BuildRequires: libspice-server-devel
|
||||
BuildRequires: spice-protocol-devel
|
||||
BuildRequires: usbredir-devel
|
||||
%endif
|
||||
%endif
|
||||
%if %{?with_qemu_traditional}0
|
||||
BuildRequires: SDL-devel
|
||||
BuildRequires: pciutils-devel
|
||||
@ -193,6 +200,7 @@ Source99: baselibs.conf
|
||||
# http://xenbits.xensource.com/ext/xenalyze
|
||||
Source20000: xenalyze.hg.tar.bz2
|
||||
# Upstream patches
|
||||
Patch1: 5124efbe-add-qxl-support.patch
|
||||
# Upstream qemu
|
||||
Patch250: VNC-Support-for-ExtendedKeyEvent-client-message.patch
|
||||
Patch251: 0001-net-move-the-tap-buffer-into-TAPState.patch
|
||||
@ -214,6 +222,7 @@ Patch311: xl-coredump-file-location.patch
|
||||
Patch330: suspend_evtchn_lock.patch
|
||||
Patch331: xenpaging.doc.patch
|
||||
Patch332: local_attach_support_for_phy.patch
|
||||
Patch333: xentop-add-support-for-qdisk.patch
|
||||
# Qemu traditional
|
||||
Patch350: blktap.patch
|
||||
Patch351: cdrom-removable.patch
|
||||
@ -267,6 +276,7 @@ Patch464: set-mtu-from-bridge-for-tap-interface.patch
|
||||
Patch466: aarch64-rename-PSR_MODE_ELxx-to-match-linux-headers.patch
|
||||
Patch467: libxl.add-option-to-disable-disk-cache-flushes-in-qdisk.patch
|
||||
Patch470: qemu-xen-upstream-qdisk-cache-unsafe.patch
|
||||
Patch471: qemu-xen-enable-spice-support.patch
|
||||
Patch472: tigervnc-long-press.patch
|
||||
# Hypervisor and PV driver Patches
|
||||
Patch501: x86-ioapic-ack-default.patch
|
||||
@ -487,6 +497,7 @@ Authors:
|
||||
%prep
|
||||
%setup -q -n %xen_build_dir -a 1 -a 2 -a 3 -a 4 -a 5 -a 57 -a 20000
|
||||
# Upstream patches
|
||||
%patch1 -p1
|
||||
# Upstream qemu patches
|
||||
%patch250 -p1
|
||||
%patch251 -p1
|
||||
@ -507,6 +518,7 @@ Authors:
|
||||
%patch330 -p1
|
||||
%patch331 -p1
|
||||
%patch332 -p1
|
||||
%patch333 -p1
|
||||
# Qemu traditional
|
||||
%patch350 -p1
|
||||
%patch351 -p1
|
||||
@ -560,6 +572,7 @@ Authors:
|
||||
%patch466 -p1
|
||||
%patch467 -p1
|
||||
%patch470 -p1
|
||||
%patch471 -p1
|
||||
%patch472 -p1
|
||||
# Hypervisor and PV driver Patches
|
||||
%patch501 -p1
|
||||
@ -636,6 +649,11 @@ if diff -u xen/Makefile~ xen/Makefile
|
||||
then
|
||||
: no changes?
|
||||
fi
|
||||
%ifarch x86_64
|
||||
%if 0%{?suse_version} > 1230
|
||||
export QEMU_XEN_ENABLE_SPICE="--enable-spice --enable-usb-redir"
|
||||
%endif
|
||||
%endif
|
||||
configure_flags=
|
||||
%if %{?with_stubdom}0
|
||||
configure_flags=--enable-stubdom
|
||||
|
495
xentop-add-support-for-qdisk.patch
Normal file
495
xentop-add-support-for-qdisk.patch
Normal file
@ -0,0 +1,495 @@
|
||||
Index: xen-4.5.0-testing/tools/xenstat/libxenstat/Makefile
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/Makefile
|
||||
+++ xen-4.5.0-testing/tools/xenstat/libxenstat/Makefile
|
||||
@@ -24,7 +24,7 @@ MINOR=0
|
||||
LIB=src/libxenstat.a
|
||||
SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR)
|
||||
SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so
|
||||
-OBJECTS-y=src/xenstat.o
|
||||
+OBJECTS-y=src/xenstat.o src/xenstat_qmp.o
|
||||
OBJECTS-$(CONFIG_Linux) += src/xenstat_linux.o
|
||||
OBJECTS-$(CONFIG_SunOS) += src/xenstat_solaris.o
|
||||
OBJECTS-$(CONFIG_NetBSD) += src/xenstat_netbsd.o
|
||||
Index: xen-4.5.0-testing/tools/xenstat/xentop/Makefile
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/xenstat/xentop/Makefile
|
||||
+++ xen-4.5.0-testing/tools/xenstat/xentop/Makefile
|
||||
@@ -19,7 +19,7 @@ all install xentop:
|
||||
else
|
||||
|
||||
CFLAGS += -DGCC_PRINTF -Werror $(CFLAGS_libxenstat)
|
||||
-LDLIBS += $(LDLIBS_libxenstat) $(CURSES_LIBS) $(SOCKET_LIBS) -lm
|
||||
+LDLIBS += $(LDLIBS_libxenstat) $(CURSES_LIBS) $(SOCKET_LIBS) -lm -lyajl
|
||||
CFLAGS += -DHOST_$(XEN_OS)
|
||||
|
||||
# Include configure output (config.h) to headers search path
|
||||
Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_priv.h
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/src/xenstat_priv.h
|
||||
+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_priv.h
|
||||
@@ -109,5 +109,7 @@ extern int xenstat_collect_networks(xens
|
||||
extern void xenstat_uninit_networks(xenstat_handle * handle);
|
||||
extern int xenstat_collect_vbds(xenstat_node * node);
|
||||
extern void xenstat_uninit_vbds(xenstat_handle * handle);
|
||||
+extern void read_attributes_qdisk(xenstat_node * node);
|
||||
+extern xenstat_vbd *xenstat_save_vbd(xenstat_domain * domain, xenstat_vbd * vbd);
|
||||
|
||||
#endif /* XENSTAT_PRIV_H */
|
||||
Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/src/xenstat.c
|
||||
+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat.c
|
||||
@@ -657,6 +657,24 @@ static void xenstat_uninit_xen_version(x
|
||||
* VBD functions
|
||||
*/
|
||||
|
||||
+/* Save VBD information */
|
||||
+xenstat_vbd *xenstat_save_vbd(xenstat_domain *domain, xenstat_vbd *vbd)
|
||||
+{
|
||||
+ if (domain->vbds == NULL) {
|
||||
+ domain->num_vbds = 1;
|
||||
+ domain->vbds = malloc(sizeof(xenstat_vbd));
|
||||
+ } else {
|
||||
+ domain->num_vbds++;
|
||||
+ domain->vbds = realloc(domain->vbds,
|
||||
+ domain->num_vbds *
|
||||
+ sizeof(xenstat_vbd));
|
||||
+ }
|
||||
+ if (domain->vbds != NULL)
|
||||
+ domain->vbds[domain->num_vbds - 1] = *vbd;
|
||||
+
|
||||
+ return domain->vbds;
|
||||
+}
|
||||
+
|
||||
/* Free VBD information */
|
||||
static void xenstat_free_vbds(xenstat_node * node)
|
||||
{
|
||||
Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_linux.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/xenstat/libxenstat/src/xenstat_linux.c
|
||||
+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_linux.c
|
||||
@@ -417,6 +417,9 @@ int xenstat_collect_vbds(xenstat_node *
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Get qdisk statistics */
|
||||
+ read_attributes_qdisk(node);
|
||||
+
|
||||
rewinddir(priv->sysfsvbd);
|
||||
|
||||
for(dp = readdir(priv->sysfsvbd); dp != NULL ;
|
||||
@@ -477,18 +480,10 @@ int xenstat_collect_vbds(xenstat_node *
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (domain->vbds == NULL) {
|
||||
- domain->num_vbds = 1;
|
||||
- domain->vbds = malloc(sizeof(xenstat_vbd));
|
||||
- } else {
|
||||
- domain->num_vbds++;
|
||||
- domain->vbds = realloc(domain->vbds,
|
||||
- domain->num_vbds *
|
||||
- sizeof(xenstat_vbd));
|
||||
- }
|
||||
- if (domain->vbds == NULL)
|
||||
+ if ((xenstat_save_vbd(domain, &vbd)) == NULL) {
|
||||
+ perror("Allocation error");
|
||||
return 0;
|
||||
- domain->vbds[domain->num_vbds - 1] = vbd;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 1;
|
||||
Index: xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_qmp.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-4.5.0-testing/tools/xenstat/libxenstat/src/xenstat_qmp.c
|
||||
@@ -0,0 +1,387 @@
|
||||
+/* libxenstat: statistics-collection library for Xen
|
||||
+ *
|
||||
+ * 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.
|
||||
+ */
|
||||
+
|
||||
+#include <fcntl.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <sys/poll.h>
|
||||
+#include <sys/un.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <unistd.h>
|
||||
+#include "yajl/yajl_tree.h"
|
||||
+
|
||||
+#include <xenctrl.h>
|
||||
+
|
||||
+#include "xenstat_priv.h"
|
||||
+
|
||||
+static unsigned char *qmp_query(int, char *);
|
||||
+
|
||||
+enum query_blockstats {
|
||||
+ QMP_STATS_RETURN = 0,
|
||||
+ QMP_STATS_DEVICE = 1,
|
||||
+ QMP_STATS = 2,
|
||||
+ QMP_RD_BYTES = 3,
|
||||
+ QMP_WR_BYTES = 4,
|
||||
+ QMP_RD_OPERATIONS = 5,
|
||||
+ QMP_WR_OPERATIONS = 6,
|
||||
+};
|
||||
+
|
||||
+enum query_block {
|
||||
+ QMP_BLOCK_RETURN = 0,
|
||||
+ QMP_BLOCK_DEVICE = 1,
|
||||
+ QMP_INSERTED = 2,
|
||||
+ QMP_FILE = 3,
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/* Given the qmp device name, get the image filename associated with it */
|
||||
+static char *qmp_get_block_image(xenstat_node *node, char *qmp_devname, int qfd)
|
||||
+{
|
||||
+ char errbuf[1024], *tmp, *file = NULL;
|
||||
+ char *query_block_cmd = "{ \"execute\": \"query-block\" }";
|
||||
+ static const char *const qblock[] = {
|
||||
+ [ QMP_BLOCK_RETURN ] = "return",
|
||||
+ [ QMP_BLOCK_DEVICE ] = "device",
|
||||
+ [ QMP_INSERTED ] = "inserted",
|
||||
+ [ QMP_FILE ] = "file",
|
||||
+ };
|
||||
+ const char *ptr[] = {0, 0};
|
||||
+ unsigned char *qmp_stats;
|
||||
+ yajl_val info, ret_obj, dev_obj, n;
|
||||
+ int i;
|
||||
+
|
||||
+ if ((qmp_stats = qmp_query(qfd, query_block_cmd)) == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* Use libyajl version 2.1.x or newer for the tree parser feature with bug fixes */
|
||||
+ if ((info = yajl_tree_parse((char *)qmp_stats, errbuf, sizeof(errbuf))) == NULL) {
|
||||
+ free(qmp_stats);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ptr[0] = qblock[QMP_BLOCK_RETURN]; /* "return" */
|
||||
+ if ((ret_obj = yajl_tree_get(info, ptr, yajl_t_array)) == NULL)
|
||||
+ goto done;
|
||||
+
|
||||
+ for (i=0; i<YAJL_GET_ARRAY(ret_obj)->len; i++) {
|
||||
+ n = YAJL_GET_ARRAY(ret_obj)->values[i];
|
||||
+
|
||||
+ ptr[0] = qblock[QMP_BLOCK_DEVICE]; /* "device" */
|
||||
+ if ((dev_obj = yajl_tree_get(n, ptr, yajl_t_any)) != NULL) {
|
||||
+ tmp = YAJL_GET_STRING(dev_obj);
|
||||
+ if (strcmp(qmp_devname, tmp))
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ continue;
|
||||
+
|
||||
+ ptr[0] = qblock[QMP_INSERTED]; /* "inserted" */
|
||||
+ n = yajl_tree_get(n, ptr, yajl_t_any);
|
||||
+ if (n) {
|
||||
+ ptr[0] = qblock[QMP_FILE]; /* "file" */
|
||||
+ n = yajl_tree_get(n, ptr, yajl_t_any);
|
||||
+ if (n && YAJL_IS_STRING(n)) {
|
||||
+ tmp = YAJL_GET_STRING(n);
|
||||
+ file = malloc(strlen(tmp)+1);
|
||||
+ if (file != NULL)
|
||||
+ strcpy(file, tmp);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+done:
|
||||
+ yajl_tree_free(info);
|
||||
+ return file;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Given a QMP device name, find the associated xenstore qdisk device id */
|
||||
+static void get_xs_devid_from_qmp_devname(xenstat_node * node, unsigned int domid, char *qmp_devname,
|
||||
+ unsigned int *dev, unsigned int *sector_size, int qfd)
|
||||
+{
|
||||
+ char **dev_ids, *tmp, *ptr, *image, path[80];
|
||||
+ unsigned int num_dev_ids;
|
||||
+ int i, devid;
|
||||
+
|
||||
+ /* Get all the qdisk dev IDs associated with the this VM */
|
||||
+ snprintf(path, sizeof(path),"/local/domain/0/backend/qdisk/%i", domid);
|
||||
+ dev_ids = xs_directory(node->handle->xshandle, XBT_NULL, path, &num_dev_ids);
|
||||
+ if (dev_ids == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Get the filename of the image associated with this QMP device */
|
||||
+ image = qmp_get_block_image(node, qmp_devname, qfd);
|
||||
+ if (image == NULL) {
|
||||
+ free(dev_ids);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Look for a matching image in xenstore */
|
||||
+ for (i=0; i<num_dev_ids; i++) {
|
||||
+ devid = atoi(dev_ids[i]);
|
||||
+ /* Get the xenstore name of the image */
|
||||
+ snprintf(path, sizeof(path),"/local/domain/0/backend/qdisk/%i/%i/params", domid, devid);
|
||||
+ if ((ptr = xs_read(node->handle->xshandle, XBT_NULL, path, NULL)) == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Get to actual path in string */
|
||||
+ if ((tmp = strchr(ptr, '/')) == NULL)
|
||||
+ tmp = ptr;
|
||||
+ if (!strcmp(tmp,image)) {
|
||||
+ *dev = devid;
|
||||
+ free(ptr);
|
||||
+
|
||||
+ /* Get the xenstore sector size of the image while we're here */
|
||||
+ snprintf(path, sizeof(path),"/local/domain/0/backend/qdisk/%i/%i/sector-size", domid, devid);
|
||||
+ if ((ptr = xs_read(node->handle->xshandle, XBT_NULL, path, NULL)) != NULL) {
|
||||
+ *sector_size = atoi((char *)ptr);
|
||||
+ free(ptr);
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ free(ptr);
|
||||
+ }
|
||||
+
|
||||
+ free(image);
|
||||
+ free(dev_ids);
|
||||
+}
|
||||
+
|
||||
+/* Parse the stats buffer which contains I/O data for all the disks belonging to domid */
|
||||
+static void qmp_parse_stats(xenstat_node *node, unsigned int domid, unsigned char *stats_buf, int qfd)
|
||||
+{
|
||||
+ char *qmp_devname, errbuf[1024];
|
||||
+ static const char *const qstats[] = {
|
||||
+ [ QMP_STATS_RETURN ] = "return",
|
||||
+ [ QMP_STATS_DEVICE ] = "device",
|
||||
+ [ QMP_STATS ] = "stats",
|
||||
+ [ QMP_RD_BYTES ] = "rd_bytes",
|
||||
+ [ QMP_WR_BYTES ] = "wr_bytes",
|
||||
+ [ QMP_RD_OPERATIONS ] = "rd_operations",
|
||||
+ [ QMP_WR_OPERATIONS ] = "wr_operations",
|
||||
+ };
|
||||
+ const char *ptr[] = {0, 0};
|
||||
+ yajl_val info, ret_obj, stats_obj, n;
|
||||
+ xenstat_vbd vbd;
|
||||
+ xenstat_domain *domain;
|
||||
+ unsigned int sector_size = 512;
|
||||
+ int i, j;
|
||||
+
|
||||
+ /* Use libyajl version 2.0.3 or newer for the tree parser feature */
|
||||
+ if ((info = yajl_tree_parse((char *)stats_buf, errbuf, sizeof(errbuf))) == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ ptr[0] = qstats[QMP_STATS_RETURN]; /* "return" */
|
||||
+ if ((ret_obj = yajl_tree_get(info, ptr, yajl_t_array)) == NULL)
|
||||
+ goto done;
|
||||
+
|
||||
+ /* Array of devices */
|
||||
+ for (i=0; i<YAJL_GET_ARRAY(ret_obj)->len; i++) {
|
||||
+ memset(&vbd, 0, sizeof(xenstat_vbd));
|
||||
+ qmp_devname = NULL;
|
||||
+ stats_obj = YAJL_GET_ARRAY(ret_obj)->values[i];
|
||||
+
|
||||
+ ptr[0] = qstats[QMP_STATS_DEVICE]; /* "device" */
|
||||
+ if ((n = yajl_tree_get(stats_obj, ptr, yajl_t_any)) != NULL)
|
||||
+ qmp_devname = YAJL_GET_STRING(n);
|
||||
+
|
||||
+ ptr[0] = qstats[QMP_STATS]; /* "stats" */
|
||||
+ stats_obj = yajl_tree_get(stats_obj, ptr, yajl_t_object);
|
||||
+ if (stats_obj && YAJL_IS_OBJECT(stats_obj)) {
|
||||
+ for (j=3; j<7; j++) {
|
||||
+ ptr[0] = qstats[j];
|
||||
+ n = yajl_tree_get(stats_obj, ptr, yajl_t_number);
|
||||
+ if (n && YAJL_IS_NUMBER(n)) {
|
||||
+ switch(j) {
|
||||
+ case QMP_RD_BYTES: /* "rd_bytes" */
|
||||
+ vbd.rd_sects = YAJL_GET_INTEGER(n) / sector_size;
|
||||
+ break;
|
||||
+ case QMP_WR_BYTES: /* "wr_bytes" */
|
||||
+ vbd.wr_sects = YAJL_GET_INTEGER(n) / sector_size;
|
||||
+ break;
|
||||
+ case QMP_RD_OPERATIONS: /* "rd_operations" */
|
||||
+ vbd.rd_reqs = YAJL_GET_INTEGER(n);
|
||||
+ break;
|
||||
+ case QMP_WR_OPERATIONS: /* "wr_operations" */
|
||||
+ vbd.wr_reqs = YAJL_GET_INTEGER(n);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ /* With the QMP device name, lookup the xenstore qdisk device ID and set vdb.dev */
|
||||
+ if (qmp_devname)
|
||||
+ get_xs_devid_from_qmp_devname(node, domid, qmp_devname, &vbd.dev, §or_size, qfd);
|
||||
+ if ((domain = xenstat_node_domain(node, domid)) == NULL)
|
||||
+ continue;
|
||||
+ if ((xenstat_save_vbd(domain, &vbd)) == NULL)
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+done:
|
||||
+ yajl_tree_free(info);
|
||||
+}
|
||||
+
|
||||
+/* Write a command via the QMP */
|
||||
+static size_t qmp_write(int qfd, char *cmd, size_t cmd_len)
|
||||
+{
|
||||
+ size_t pos = 0;
|
||||
+ ssize_t res;
|
||||
+
|
||||
+ while (cmd_len > pos) {
|
||||
+ res = write(qfd, cmd + pos, cmd_len - pos);
|
||||
+ switch (res) {
|
||||
+ case -1:
|
||||
+ if (errno == EINTR || errno == EAGAIN)
|
||||
+ continue;
|
||||
+ return 0;
|
||||
+ case 0:
|
||||
+ errno = EPIPE;
|
||||
+ return pos;
|
||||
+ default:
|
||||
+ pos += (size_t)res;
|
||||
+ }
|
||||
+ }
|
||||
+ return pos;
|
||||
+}
|
||||
+
|
||||
+/* Read the data sent in response to a QMP execute query. Returns 1 for success */
|
||||
+static int qmp_read(int qfd, unsigned char **qstats)
|
||||
+{
|
||||
+ unsigned char buf[1024], *ptr = NULL;
|
||||
+ struct pollfd pfd[2];
|
||||
+ int n, qsize = 0;
|
||||
+
|
||||
+ pfd[0].fd = qfd;
|
||||
+ pfd[0].events = POLLIN;
|
||||
+ while ((n = poll(pfd, POLLIN, 10)) > 0) {
|
||||
+ if (pfd[0].revents & POLLIN) {
|
||||
+ if ((n = read(qfd, buf, sizeof(buf))) < 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (ptr == NULL)
|
||||
+ ptr = malloc(n+1);
|
||||
+ else
|
||||
+ ptr = realloc(ptr, qsize+n+1);
|
||||
+ if (ptr == NULL)
|
||||
+ return 0;
|
||||
+ memcpy(&ptr[qsize], buf, n);
|
||||
+ qsize += n;
|
||||
+ ptr[qsize] = 0;
|
||||
+ *qstats = ptr;
|
||||
+ }
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/* With the given cmd, query QMP for requested data. Returns allocated buffer containing data or NULL */
|
||||
+static unsigned char *qmp_query(int qfd, char *cmd)
|
||||
+{
|
||||
+ unsigned char *qstats = NULL;
|
||||
+ int n;
|
||||
+
|
||||
+ n = strlen(cmd);
|
||||
+ if (qmp_write(qfd, cmd, n) != n)
|
||||
+ return NULL;
|
||||
+ if (!qmp_read(qfd, &qstats))
|
||||
+ return NULL;
|
||||
+ return qstats;
|
||||
+}
|
||||
+
|
||||
+/* Returns a socket connected to the QMP socket. Returns -1 on failure. */
|
||||
+static int qmp_connect(char *path)
|
||||
+{
|
||||
+ struct sockaddr_un sun;
|
||||
+ int s;
|
||||
+
|
||||
+ if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||
+ return -1;
|
||||
+ (void)fcntl(s, F_SETFD, 1);
|
||||
+
|
||||
+ memset(&sun, 0, sizeof(struct sockaddr_un));
|
||||
+ sun.sun_family = AF_UNIX;
|
||||
+
|
||||
+ if (strlen(path) >= sizeof(sun.sun_path)) {
|
||||
+ close(s);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ strcpy(sun.sun_path, path);
|
||||
+ if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
|
||||
+ close(s);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return s;
|
||||
+}
|
||||
+
|
||||
+/* Get all the active domains */
|
||||
+static xc_domaininfo_t *get_domain_ids(int *num_doms)
|
||||
+{
|
||||
+ xc_domaininfo_t *dominfo;
|
||||
+ xc_interface *xc_handle;
|
||||
+
|
||||
+ dominfo = calloc(1024, sizeof(xc_domaininfo_t));
|
||||
+ if (dominfo == NULL)
|
||||
+ return NULL;
|
||||
+ xc_handle = xc_interface_open(0,0,0);
|
||||
+ *num_doms = xc_domain_getinfolist(xc_handle, 0, 1024, dominfo);
|
||||
+ xc_interface_close(xc_handle);
|
||||
+ return dominfo;
|
||||
+}
|
||||
+
|
||||
+/* Gather the qdisk statistics by querying QMP */
|
||||
+void read_attributes_qdisk(xenstat_node * node)
|
||||
+{
|
||||
+ char *cmd_mode = "{ \"execute\": \"qmp_capabilities\" }";
|
||||
+ char *query_blockstats_cmd = "{ \"execute\": \"query-blockstats\" }";
|
||||
+ xc_domaininfo_t *dominfo = NULL;
|
||||
+ unsigned char *qmp_stats, *val;
|
||||
+ char path[80];
|
||||
+ int i, qfd, num_doms;
|
||||
+
|
||||
+ dominfo = get_domain_ids(&num_doms);
|
||||
+ if (dominfo == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ for (i=0; i<num_doms; i++) {
|
||||
+ if (dominfo[i].domain <= 0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Verify that qdisk disks are used with this VM */
|
||||
+ snprintf(path, sizeof(path),"/local/domain/0/backend/qdisk/%i", dominfo[i].domain);
|
||||
+ if ((val = xs_read(node->handle->xshandle, XBT_NULL, path, NULL)) == NULL)
|
||||
+ continue;
|
||||
+ free(val);
|
||||
+
|
||||
+ /* Connect to this VMs QMP socket */
|
||||
+ snprintf(path, sizeof(path), "/var/run/xen/qmp-libxl-%i", dominfo[i].domain);
|
||||
+ if ((qfd = qmp_connect(path)) < 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* First enable QMP capabilities so that we can query for data */
|
||||
+ if ((qmp_stats = qmp_query(qfd, cmd_mode)) != NULL) {
|
||||
+ free(qmp_stats);
|
||||
+ /* Query QMP for this VMs blockstats */
|
||||
+ if ((qmp_stats = qmp_query(qfd, query_blockstats_cmd)) != NULL) {
|
||||
+ qmp_parse_stats(node, dominfo[i].domain, qmp_stats, qfd);
|
||||
+ free(qmp_stats);
|
||||
+ }
|
||||
+ }
|
||||
+ close(qfd);
|
||||
+ }
|
||||
+
|
||||
+ free(dominfo);
|
||||
+}
|
||||
+
|
@ -10,7 +10,7 @@ Index: xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
===================================================================
|
||||
--- xen-4.5.0-testing.orig/tools/libxl/xl_cmdimpl.c
|
||||
+++ xen-4.5.0-testing/tools/libxl/xl_cmdimpl.c
|
||||
@@ -2092,7 +2092,7 @@ static int handle_domain_death(uint32_t
|
||||
@@ -2094,7 +2094,7 @@ static int handle_domain_death(uint32_t
|
||||
char *corefile;
|
||||
int rc;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user