Hello community, here is the log from the commit of package xen for openSUSE:Factory checked in at 2015-03-30 19:31:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xen (Old) and /work/SRC/openSUSE:Factory/.xen.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xen" Changes: -------- --- /work/SRC/openSUSE:Factory/xen/xen.changes 2015-03-09 10:00:12.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.xen.new/xen.changes 2015-03-30 19:31:26.000000000 +0200 @@ -1,0 +2,14 @@ +Mon Mar 16 10:14:15 MDT 2015 - carn...@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 - carn...@suse.com + +- bnc#921842 - Xentop doesn't display disk statistics for VMs using + qdisks + xentop-add-support-for-qdisk.patch + +------------------------------------------------------------------- New: ---- 5124efbe-add-qxl-support.patch qemu-xen-enable-spice-support.patch xentop-add-support-for-qdisk.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xen.spec ++++++ --- /var/tmp/diff_new_pack.PCEqP5/_old 2015-03-30 19:31:29.000000000 +0200 +++ /var/tmp/diff_new_pack.PCEqP5/_new 2015-03-30 19:31:29.000000000 +0200 @@ -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: 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 @@ # 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 @@ 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 @@ 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 @@ %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 @@ %patch330 -p1 %patch331 -p1 %patch332 -p1 +%patch333 -p1 # Qemu traditional %patch350 -p1 %patch351 -p1 @@ -560,6 +572,7 @@ %patch466 -p1 %patch467 -p1 %patch470 -p1 +%patch471 -p1 %patch472 -p1 # Hypervisor and PV driver Patches %patch501 -p1 @@ -636,6 +649,11 @@ 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 ++++++ 5124efbe-add-qxl-support.patch ++++++ 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); ++++++ libxl.pvscsi.patch ++++++ --- /var/tmp/diff_new_pack.PCEqP5/_old 2015-03-30 19:31:29.000000000 +0200 +++ /var/tmp/diff_new_pack.PCEqP5/_new 2015-03-30 19:31:29.000000000 +0200 @@ -503,7 +503,7 @@ =================================================================== --- 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 @@ =================================================================== --- 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 @@ 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 @@ ("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 @@ 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; } ++++++ libxl.set-migration-constraints-from-cmdline.patch ++++++ --- /var/tmp/diff_new_pack.PCEqP5/_old 2015-03-30 19:31:29.000000000 +0200 +++ /var/tmp/diff_new_pack.PCEqP5/_new 2015-03-30 19:31:29.000000000 +0200 @@ -387,7 +387,7 @@ =================================================================== --- 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 @@ 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 @@ 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 @@ " (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 @@ 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 @@ } 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; } ++++++ qemu-xen-enable-spice-support.patch ++++++ 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) \ ++++++ xentop-add-support-for-qdisk.patch ++++++ 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); +} + ++++++ xl-coredump-file-location.patch ++++++ --- /var/tmp/diff_new_pack.PCEqP5/_old 2015-03-30 19:31:29.000000000 +0200 +++ /var/tmp/diff_new_pack.PCEqP5/_new 2015-03-30 19:31:29.000000000 +0200 @@ -10,7 +10,7 @@ =================================================================== --- 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;