---
hw/net/vmxnet3.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
Index: xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c
+++ xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c
@@ -1134,8 +1134,13 @@ static void vmxnet3_reset_mac(VMXNET3Sta
static void vmxnet3_deactivate_device(VMXNET3State *s)
{
- VMW_CBPRN("Deactivating vmxnet3...");
- s->device_active = false;
+ if (s->device_active) {
+ VMW_CBPRN("Deactivating vmxnet3...");
+ vmxnet_tx_pkt_reset(s->tx_pkt);
+ vmxnet_tx_pkt_uninit(s->tx_pkt);
+ vmxnet_rx_pkt_uninit(s->rx_pkt);
+ s->device_active = false;
+ }
}
static void vmxnet3_reset(VMXNET3State *s)
@@ -1144,7 +1149,6 @@ static void vmxnet3_reset(VMXNET3State *
vmxnet3_deactivate_device(s);
vmxnet3_reset_interrupt_states(s);
- vmxnet_tx_pkt_reset(s->tx_pkt);
s->drv_shmem = 0;
s->tx_sop = true;
s->skip_current_tx_pkt = false;
@@ -1361,6 +1365,12 @@ static void vmxnet3_activate_device(VMXN
return;
}
+ /* Verify if device is active */
+ if (s->device_active) {
+ VMW_CFPRN("Vmxnet3 device is active");
+ return;
+ }
+
vmxnet3_adjust_by_guest_type(s);
vmxnet3_update_features(s);
vmxnet3_update_pm_state(s);
@@ -1554,7 +1564,7 @@ static void vmxnet3_handle_command(VMXNE
break;
case VMXNET3_CMD_QUIESCE_DEV:
- VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device");
+ VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device");
vmxnet3_deactivate_device(s);
break;
@@ -1659,7 +1669,7 @@ vmxnet3_io_bar1_write(void *opaque,
* shared address only after we get the high part
*/
if (0 == val) {
- s->device_active = false;
+ vmxnet3_deactivate_device(s);
}
s->temp_shared_guest_driver_memory = val;
s->drv_shmem = 0;
@@ -1939,9 +1949,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VM
static void vmxnet3_net_uninit(VMXNET3State *s)
{
g_free(s->mcast_list);
- vmxnet_tx_pkt_reset(s->tx_pkt);
- vmxnet_tx_pkt_uninit(s->tx_pkt);
- vmxnet_rx_pkt_uninit(s->rx_pkt);
+ vmxnet3_deactivate_device(s);
qemu_del_nic(s->nic);
}
++++++ README.SUSE ++++++
++++ 643 lines (skipped)
++++++ VNC-Support-for-ExtendedKeyEvent-client-message.patch ++++++
From 9ca313aa0824f2d350a7a6c9b1ef6c47e0408f1d Mon Sep 17 00:00:00 2001
From: aliguori
Date: Sat, 23 Aug 2008 23:27:37 +0000
Subject: [PATCH] VNC: Support for ExtendedKeyEvent client message
This patch adds support for the ExtendedKeyEvent client message. This message
allows a client to send raw scan codes directly to the server. If the client
and server are using the same keymap, then it's unnecessary to use the '-k'
option with QEMU when this extension is supported.
This is extension is currently only implemented by gtk-vnc based clients
(gvncviewer, virt-manager, vinagre, etc.).
Signed-off-by: Anthony Liguori
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5076 c046a42c-6fe2-441c-8c8c-71466251a162
---
vnc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 50 insertions(+), 9 deletions(-)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
@@ -1285,35 +1285,22 @@ static void press_key_altgr_down(VncStat
}
}
-static void do_key_event(VncState *vs, int down, uint32_t sym)
+static void do_key_event(VncState *vs, int down, int keycode, int sym, int shift)
{
- int keycode;
int shift_keys = 0;
- int shift = 0;
int keypad = 0;
int altgr = 0;
int altgr_keys = 0;
if (is_graphic_console()) {
- if (sym >= 'A' && sym <= 'Z') {
- sym = sym - 'A' + 'a';
- shift = 1;
- }
- else {
+ if (!shift)
shift = keysym_is_shift(vs->kbd_layout, sym & 0xFFFF);
- }
altgr = keysym_is_altgr(vs->kbd_layout, sym & 0xFFFF);
}
shift_keys = vs->modifiers_state[0x2a] | vs->modifiers_state[0x36];
altgr_keys = vs->modifiers_state[0xb8];
- keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
- if (keycode == 0) {
- fprintf(stderr, "Key lost : keysym=0x%x(%d)\n", sym, sym);
- return;
- }
-
/* QEMU console switch */
switch(keycode) {
case 0x2a: /* Left Shift */
@@ -1445,7 +1432,25 @@ static void do_key_event(VncState *vs, i
static void key_event(VncState *vs, int down, uint32_t sym)
{
- do_key_event(vs, down, sym);
+ int keycode;
+ int shift = 0;
+
+ if (sym >= 'A' && sym <= 'Z' && is_graphic_console()) {
+ sym = sym - 'A' + 'a';
+ shift = 1;
+ }
+ keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
+ do_key_event(vs, down, keycode, sym, shift);
+}
+
+static void ext_key_event(VncState *vs, int down,
+ uint32_t sym, uint16_t keycode)
+{
+ /* if the user specifies a keyboard layout, always use it */
+ if (keyboard_layout)
+ key_event(vs, down, sym);
+ else
+ do_key_event(vs, down, keycode, sym, 0);
}
static void framebuffer_set_updated(VncState *vs, int x, int y, int w, int h)
@@ -1534,6 +1539,15 @@ static void framebuffer_update_request(V
qemu_mod_timer(vs->timer, qemu_get_clock(rt_clock));
}
+static void send_ext_key_event_ack(VncState *vs)
+{
+ vnc_write_u8(vs, 0);
+ vnc_write_u8(vs, 0);
+ vnc_write_u16(vs, 1);
+ vnc_framebuffer_update(vs, 0, 0, ds_get_width(vs->ds), ds_get_height(vs->ds), -258);
+ vnc_flush(vs);
+}
+
static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
{
int i;
@@ -1562,6 +1576,9 @@ static void set_encodings(VncState *vs,
case -257:
vs->has_pointer_type_change = 1;
break;
+ case -258:
+ send_ext_key_event_ack(vs);
+ break;
case 0x574D5669:
vs->has_WMVi = 1;
default:
@@ -1774,6 +1791,24 @@ static int protocol_client_msg(VncState
client_cut_text(vs, read_u32(data, 4), (char *)(data + 8));
break;
+ case 255:
+ if (len == 1)
+ return 2;
+
+ switch (read_u8(data, 1)) {
+ case 0:
+ if (len == 2)
+ return 12;
+
+ ext_key_event(vs, read_u16(data, 2),
+ read_u32(data, 4), read_u32(data, 8));
+ break;
+ default:
+ printf("Msg: %d\n", read_u16(data, 0));
+ vnc_client_error(vs);
+ break;
+ }
+ break;
default:
printf("Msg: %d\n", data[0]);
vnc_client_error(vs);
@@ -2445,10 +2480,11 @@ void vnc_display_init(DisplayState *ds)
vs->ds = ds;
- if (!keyboard_layout)
- keyboard_layout = "en-us";
+ if (keyboard_layout)
+ vs->kbd_layout = init_keyboard_layout(keyboard_layout);
+ else
+ vs->kbd_layout = init_keyboard_layout("en-us");
- vs->kbd_layout = init_keyboard_layout(keyboard_layout);
if (!vs->kbd_layout)
exit(1);
vs->modifiers_state[0x45] = 1; /* NumLock on - on boot */
++++++ aarch64-rename-PSR_MODE_ELxx-to-match-linux-headers.patch ++++++
From 98abe3b337e69371678859c4cfd19df61aebb0d9 Mon Sep 17 00:00:00 2001
From: Olaf Hering
Date: Sun, 2 Feb 2014 20:42:42 +0100
Subject: aarch64: rename PSR_MODE_ELxx to match linux headers
https://bugs.launchpad.net/linaro-aarch64/+bug/1169164
Signed-off-by: Olaf Hering
---
xen/include/public/arch-arm.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index 7496556..95f2a7c 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -342,13 +342,13 @@ typedef uint64_t xen_callback_t;
/* 64 bit modes */
#define PSR_MODE_BIT 0x10 /* Set iff AArch32 */
-#define PSR_MODE_EL3h 0x0d
-#define PSR_MODE_EL3t 0x0c
-#define PSR_MODE_EL2h 0x09
-#define PSR_MODE_EL2t 0x08
-#define PSR_MODE_EL1h 0x05
-#define PSR_MODE_EL1t 0x04
-#define PSR_MODE_EL0t 0x00
+#define PSR_MODE_EL3h 0x0000000d
+#define PSR_MODE_EL3t 0x0000000c
+#define PSR_MODE_EL2h 0x00000009
+#define PSR_MODE_EL2t 0x00000008
+#define PSR_MODE_EL1h 0x00000005
+#define PSR_MODE_EL1t 0x00000004
+#define PSR_MODE_EL0t 0x00000000
#define PSR_GUEST32_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
#define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
++++++ 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
Signed-off-by: Zhou Peng
Acked-by: Stefano Stabellini
Acked-by: Ian Jackson
Acked-by: George Dunlap
---
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.4.3-testing/docs/man/xl.cfg.pod.5
===================================================================
--- xen-4.4.3-testing.orig/docs/man/xl.cfg.pod.5
+++ xen-4.4.3-testing/docs/man/xl.cfg.pod.5
@@ -1084,6 +1084,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
Select a standard VGA card with VBE (VESA BIOS Extensions) as the
@@ -1095,9 +1098,14 @@ This option is deprecated, use vga="stdv
=item B
-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
Allow access to the display via the VNC protocol. This enables the
Index: xen-4.4.3-testing/tools/libxl/libxl_create.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_create.c
+++ xen-4.4.3-testing/tools/libxl/libxl_create.c
@@ -230,6 +230,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;
@@ -254,6 +258,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.4.3-testing/tools/libxl/libxl_dm.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_dm.c
+++ xen-4.4.3-testing/tools/libxl/libxl_dm.c
@@ -235,6 +235,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) {
@@ -563,6 +565,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.4.3-testing/tools/libxl/libxl_types.idl
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_types.idl
+++ xen-4.4.3-testing/tools/libxl/libxl_types.idl
@@ -154,6 +154,7 @@ libxl_vga_interface_type = Enumeration("
(1, "CIRRUS"),
(2, "STD"),
(3, "NONE"),
+ (4, "QXL"),
], init_val = 1)
libxl_vendor_device = Enumeration("vendor_device", [
Index: xen-4.4.3-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.4.3-testing/tools/libxl/xl_cmdimpl.c
@@ -1678,6 +1678,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);
++++++ altgr_2.patch ++++++
When access domU from Windows VNC client, spanish keyboard altgr key
doesn't work. According to log info, we found that the keycodes passed
from vncclient to qemu vncserver have something wrong. When altgr and "2"
pressed, keycodes vncserver receives are:
ALT_R down,
CTRL_L down,
CTRL_L up,
ATL_R up,
"2" down,
"2" up,
...
Since when send "2" down, there is no altgr modifier, the char displayed
on screen will be "2" but not "@".
To solve this problem, there is another patch applied by upstream which
sends an additional altgr modifier before "2" down in the above case.
It works well when domU is windows, but on sles10 sp3 domU, sometimes it
display "@" and sometimes it still displays "2", especially when press
altgr+2 continuously.
For the sles10 sp3 domU problem, maybe because there are two many alt_r (same
keycode as altgr on "es") up and down events and the domU OS couldn't handle
it well.
To furtherly solve this problem, I write this patch, when vncserver
is "es" and receives a alt_r keysym (this is already abnormal since "es" has
no alt_r), then treat the alt_r as alt_l. This can avoid too many altgr
keycodes up and down events and make sure the intentionally added altgr keycode can take effect.
Signed-off by Chunyan Liu (cyliu@novell.com)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
@@ -1440,6 +1440,9 @@ static void key_event(VncState *vs, int
int keycode;
int shift = 0;
+ if ( sym == 0xffea && keyboard_layout && !strcmp(keyboard_layout,"es") )
+ sym = 0xffe9;
+
if (sym >= 'A' && sym <= 'Z' && is_graphic_console()) {
sym = sym - 'A' + 'a';
shift = 1;
++++++ baselibs.conf ++++++
xen-libs
++++++ bdrv_default_rwflag.patch ++++++
Subject: modify default read/write flag in bdrv_init.
Signed-off by Chunyan Liu
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vl.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
@@ -2627,6 +2627,8 @@ int drive_init(struct drive_opt *arg, in
strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));
nb_drives++;
+ bdrv_flags = BDRV_O_RDWR;
+
switch(type) {
case IF_IDE:
case IF_XEN:
@@ -2640,6 +2642,7 @@ int drive_init(struct drive_opt *arg, in
break;
case MEDIA_CDROM:
bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
+ bdrv_flags &= ~BDRV_O_RDWR;
break;
}
break;
@@ -2660,7 +2663,6 @@ int drive_init(struct drive_opt *arg, in
}
if (!file[0])
return -2;
- bdrv_flags = 0;
if (snapshot) {
bdrv_flags |= BDRV_O_SNAPSHOT;
cache = 2; /* always use write-back with snapshot */
++++++ bdrv_open2_fix_flags.patch ++++++
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.c
@@ -350,7 +350,7 @@ int bdrv_file_open(BlockDriverState **pb
int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
{
- return bdrv_open2(bs, filename, flags, NULL);
+ return bdrv_open2(bs, filename, flags|BDRV_O_RDWR, NULL);
}
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
@@ -419,12 +419,13 @@ int bdrv_open2(BlockDriverState *bs, con
}
bs->drv = drv;
bs->opaque = qemu_mallocz(drv->instance_size);
- /* Note: for compatibility, we open disk image files as RDWR, and
- RDONLY as fallback */
if (!(flags & BDRV_O_FILE))
- open_flags = (flags & BDRV_O_ACCESS) | (flags & BDRV_O_CACHE_MASK);
+ open_flags = flags;
else
open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
+ if (!(open_flags & BDRV_O_RDWR))
+ bs->read_only = 1;
+
ret = drv->bdrv_open(bs, filename, open_flags);
if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/usb-msd.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/usb-msd.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/usb-msd.c
@@ -551,7 +551,7 @@ USBDevice *usb_msd_init(const char *file
s = qemu_mallocz(sizeof(MSDState));
bdrv = bdrv_new("usb");
- if (bdrv_open2(bdrv, filename, 0, drv) < 0)
+ if (bdrv_open2(bdrv, filename, BDRV_O_RDWR, drv) < 0)
goto fail;
s->bs = bdrv;
*pbs = bdrv;
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-img.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/qemu-img.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-img.c
@@ -32,7 +32,7 @@
#endif
/* Default to cache=writeback as data integrity is not important for qemu-tcg. */
-#define BRDV_O_FLAGS BDRV_O_CACHE_WB
+#define BDRV_O_FLAGS BDRV_O_CACHE_WB
static void QEMU_NORETURN error(const char *fmt, ...)
{
@@ -185,7 +185,7 @@ static int read_password(char *buf, int
#endif
static BlockDriverState *bdrv_new_open(const char *filename,
- const char *fmt)
+ const char *fmt, int flags)
{
BlockDriverState *bs;
BlockDriver *drv;
@@ -201,7 +201,7 @@ static BlockDriverState *bdrv_new_open(c
} else {
drv = &bdrv_raw;
}
- if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
+ if (bdrv_open2(bs, filename, flags, drv) < 0) {
error("Could not open '%s'", filename);
}
if (bdrv_is_encrypted(bs)) {
@@ -253,7 +253,7 @@ static int img_create(int argc, char **a
size = 0;
if (base_filename) {
BlockDriverState *bs;
- bs = bdrv_new_open(base_filename, NULL);
+ bs = bdrv_new_open(base_filename, NULL, BDRV_O_RDWR);
bdrv_get_geometry(bs, &size);
size *= 512;
bdrv_delete(bs);
@@ -332,7 +332,7 @@ static int img_commit(int argc, char **a
} else {
drv = NULL;
}
- if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
+ if (bdrv_open2(bs, filename, BDRV_O_RDWR, drv) < 0) {
error("Could not open '%s'", filename);
}
ret = bdrv_commit(bs);
@@ -455,7 +455,8 @@ static int img_convert(int argc, char **
total_sectors = 0;
for (bs_i = 0; bs_i < bs_n; bs_i++) {
- bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt);
+ bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt,
+ BDRV_O_CACHE_WB|BDRV_O_RDONLY);
if (!bs[bs_i])
error("Could not open '%s'", argv[optind + bs_i]);
bdrv_get_geometry(bs[bs_i], &bs_sectors);
@@ -483,7 +484,7 @@ static int img_convert(int argc, char **
}
}
- out_bs = bdrv_new_open(out_filename, out_fmt);
+ out_bs = bdrv_new_open(out_filename, out_fmt, BDRV_O_CACHE_WB|BDRV_O_RDWR);
bs_i = 0;
bs_offset = 0;
@@ -706,7 +707,7 @@ static int img_info(int argc, char **arg
} else {
drv = NULL;
}
- if (bdrv_open2(bs, filename, BRDV_O_FLAGS, drv) < 0) {
+ if (bdrv_open2(bs, filename, BDRV_O_FLAGS|BDRV_O_RDWR, drv) < 0) {
error("Could not open '%s'", filename);
}
bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
@@ -810,7 +811,7 @@ static void img_snapshot(int argc, char
if (!bs)
error("Not enough memory");
- if (bdrv_open2(bs, filename, 0, NULL) < 0) {
+ if (bdrv_open2(bs, filename, BDRV_O_RDWR, NULL) < 0) {
error("Could not open '%s'", filename);
}
++++++ bdrv_open2_flags_2.patch ++++++
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
@@ -225,6 +225,7 @@ static int open_disk(struct td_state *s,
BlockDriver* drv;
char* devname;
static int devnumber = 0;
+ int flags = readonly ? BDRV_O_RDONLY : BDRV_O_RDWR;
int i;
DPRINTF("Opening %s as blktap%d\n", path, devnumber);
@@ -247,7 +248,7 @@ static int open_disk(struct td_state *s,
DPRINTF("%s driver specified\n", drv ? drv->format_name : "No");
/* Open the image */
- if (bdrv_open2(bs, path, 0, drv) != 0) {
+ if (bdrv_open2(bs, path, flags, drv) != 0) {
fprintf(stderr, "Could not open image file %s\n", path);
return -ENOMEM;
}
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -135,7 +135,8 @@ static void insert_media(void *opaque)
else
format = &bdrv_raw;
- bdrv_open2(bs, media_filename[i], 0, format);
+ /* Temporary BDRV_O_RDWR */
+ bdrv_open2(bs, media_filename[i], BDRV_O_RDWR, format);
#ifdef CONFIG_STUBDOM
{
char *buf, *backend, *params_path, *params;
@@ -510,7 +511,8 @@ void xenstore_parse_domain_config(int hv
}
for (i = 0; i < num; i++) {
- format = NULL; /* don't know what the format is yet */
+ flags = 0;
+ format = NULL; /* don't know what the format is yet */
/* read the backend path */
xenstore_get_backend_path(&bpath, "vbd", danger_path, hvm_domid, e_danger[i]);
if (bpath == NULL)
@@ -596,6 +598,17 @@ void xenstore_parse_domain_config(int hv
format = &bdrv_raw;
}
+ /* read the mode of the device */
+ if (pasprintf(&buf, "%s/mode", bpath) == -1)
+ continue;
+ free(mode);
+ mode = xs_read(xsh, XBT_NULL, buf, &len);
+
+ if (!strcmp(mode, "r") || !strcmp(mode, "ro"))
+ flags |= BDRV_O_RDONLY;
+ if (!strcmp(mode, "w") || !strcmp(mode, "rw"))
+ flags |= BDRV_O_RDWR;
+
#if 0
/* Phantom VBDs are disabled because the use of paths
* from guest-controlled areas in xenstore is unsafe.
@@ -663,7 +676,7 @@ void xenstore_parse_domain_config(int hv
#ifdef CONFIG_STUBDOM
if (pasprintf(&danger_buf, "%s/device/vbd/%s", danger_path, e_danger[i]) == -1)
continue;
- if (bdrv_open2(bs, danger_buf, BDRV_O_CACHE_WB /* snapshot and write-back */, &bdrv_raw) == 0) {
+ if (bdrv_open2(bs, danger_buf, flags|BDRV_O_CACHE_WB /* snapshot and write-back */, &bdrv_raw) == 0) {
if (pasprintf(&buf, "%s/params", bpath) == -1)
continue;
free(params);
++++++ blktap-control-socket-race.patch ++++++
References: bnc#919098
Index: xen-4.4.1-testing/tools/blktap/drivers/blktapctrl.c
===================================================================
--- xen-4.4.1-testing.orig/tools/blktap/drivers/blktapctrl.c
+++ xen-4.4.1-testing/tools/blktap/drivers/blktapctrl.c
@@ -570,13 +570,13 @@ static int connect_qemu(blkif_t *blkif,
* disconnected. Check if it is still running.
*/
if (tapdisk_ioemu_pid == 0 || kill(tapdisk_ioemu_pid, 0)) {
+ dom0_readfd = open_ctrl_socket(wrctldev);
+ dom0_writefd = open_ctrl_socket(rdctldev);
+
/* No device model and tapdisk-ioemu doesn't run yet */
DPRINTF("Launching tapdisk-ioemu\n");
launch_tapdisk_ioemu();
- dom0_readfd = open_ctrl_socket(wrctldev);
- dom0_writefd = open_ctrl_socket(rdctldev);
-
refresh_pid = 1;
}
++++++ blktap-pv-cdrom.patch ++++++
++++ 834 lines (skipped)
++++++ blktap.patch ++++++
bug #239173
bug #242953
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -3281,7 +3281,7 @@ class XendDomainInfo:
(fn, BOOTLOADER_LOOPBACK_DEVICE))
vbd = {
- 'mode': 'RO',
+ 'mode': 'RW',
'device': BOOTLOADER_LOOPBACK_DEVICE,
}
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -447,9 +447,9 @@ void xenstore_parse_domain_config(int hv
{
char **e_danger = NULL;
char *buf = NULL;
- char *fpath = NULL, *bpath = NULL,
+ char *fpath = NULL, *bpath = NULL, *btype = NULL,
*dev = NULL, *params = NULL, *drv = NULL;
- int i, ret;
+ int i, ret, is_tap;
unsigned int len, num, hd_index, pci_devid = 0;
BlockDriverState *bs;
BlockDriver *format;
@@ -486,6 +486,14 @@ void xenstore_parse_domain_config(int hv
e_danger[i]);
if (bpath == NULL)
continue;
+ /* check to see if type is tap or not */
+ if (pasprintf(&buf, "%s/type", bpath) == -1)
+ continue;
+ free(btype);
+ btype = xs_read(xsh, XBT_NULL, buf, &len);
+ if (btype == NULL)
+ continue;
+ is_tap = !strncmp(btype, "tap", 3);
/* read the name of the device */
if (pasprintf(&buf, "%s/dev", bpath) == -1)
continue;
@@ -762,6 +770,7 @@ void xenstore_parse_domain_config(int hv
free(mode);
free(params);
free(dev);
+ free(btype);
free(bpath);
free(buf);
free(danger_buf);
++++++ blktapctrl-close-fifos.patch ++++++
Index: xen-4.4.0-testing/tools/blktap/drivers/blktapctrl.c
===================================================================
--- xen-4.4.0-testing.orig/tools/blktap/drivers/blktapctrl.c
+++ xen-4.4.0-testing/tools/blktap/drivers/blktapctrl.c
@@ -282,7 +282,7 @@ static int del_disktype(blkif_t *blkif)
* qemu-dm instance. We may close the file handle only if there is
* no other disk left for this domain.
*/
- if (dtypes[type]->use_ioemu)
+ if (dtypes[type]->use_ioemu && dtypes[type]->idnum != DISK_TYPE_AIO)
return !qemu_instance_has_disks(blkif->tappid);
/* Caller should close() if no single controller, or list is empty. */
++++++ blktapctrl-default-to-ioemu.patch ++++++
Index: xen-4.2.0-testing/tools/blktap/drivers/tapdisk.h
===================================================================
--- xen-4.2.0-testing.orig/tools/blktap/drivers/tapdisk.h
+++ xen-4.2.0-testing/tools/blktap/drivers/tapdisk.h
@@ -168,7 +168,7 @@ static disk_info_t aio_disk = {
"raw image (aio)",
"aio",
0,
- 0,
+ 1,
#ifdef TAPDISK
&tapdisk_aio,
#endif
@@ -179,7 +179,7 @@ static disk_info_t sync_disk = {
"raw image (sync)",
"sync",
0,
- 0,
+ 1,
#ifdef TAPDISK
&tapdisk_sync,
#endif
@@ -190,7 +190,7 @@ static disk_info_t vmdk_disk = {
"vmware image (vmdk)",
"vmdk",
1,
- 0,
+ 1,
#ifdef TAPDISK
&tapdisk_vmdk,
#endif
@@ -212,7 +212,7 @@ static disk_info_t qcow_disk = {
"qcow disk (qcow)",
"qcow",
0,
- 0,
+ 1,
#ifdef TAPDISK
&tapdisk_qcow,
#endif
@@ -223,7 +223,7 @@ static disk_info_t qcow2_disk = {
"qcow2 disk (qcow2)",
"qcow2",
0,
- 0,
+ 1,
#ifdef TAPDISK
&tapdisk_qcow2,
#endif
++++++ blktapctrl-disable-debug-printf.patch ++++++
Index: xen-4.2.0-testing/tools/blktap/drivers/blktapctrl.c
===================================================================
--- xen-4.2.0-testing.orig/tools/blktap/drivers/blktapctrl.c
+++ xen-4.2.0-testing/tools/blktap/drivers/blktapctrl.c
@@ -61,6 +61,9 @@
#include "list.h"
#include "xs_api.h" /* for xs_fire_next_watch() */
+#undef DPRINTF
+#define DPRINTF(_f, _a...) ((void)0)
+
#define PIDFILE "/var/run/blktapctrl.pid"
#define NUM_POLL_FDS 2
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
@@ -46,7 +46,7 @@
#define BLKTAP_CTRL_DIR "/var/run/tap"
/* If enabled, print debug messages to stderr */
-#if 1
+#if 0
#define DPRINTF(_f, _a...) fprintf(stderr, __FILE__ ":%d: " _f, __LINE__, ##_a)
#else
#define DPRINTF(_f, _a...) ((void)0)
++++++ block-dmmd ++++++
#! /bin/bash
# Usage: block-dmmd [add args | remove args]
#
# the dmmd device syntax (in xm commands/configs) is something like:
# dmmd:md;/dev/md0;md;/dev/md1;lvm;/dev/vg1/lv1
# or
# dmmd:lvm;/dev/vg1/lv1;lvm;/dev/vg1/lv2;md;/dev/md0
# device pairs (type;dev) are processed in order, with the last device
# assigned to the VM
#
# md devices can optionally:
# specify a config file through:
# md;/dev/md100(/var/xen/config/mdadm.conf)
# use an array name (mdadm -N option):
# dmmd:md;My-MD-name;lvm;/dev/vg1/lv1
#
# History:
# 2013-07-03, loic.devulder@mpsa.com:
# Partial rewrite of the script for supporting MD activation by name
# 2009-06-09, mh@novell.com:
# Emit debugging messages into a temporary file; if no longer needed,
# just comment the exec I/O redirection below
# Make variables used in functions local to avoid global overridings
# Use vgscan and vgchange where required
# Use the C locale to avoid dealing with localized messages
# Assign output from assembling an MD device to a variable to aid debugging
# We do not want to deal with localized messages:
LANG=C
LC_MESSAGES=C
export LANG LC_MESSAGES
dir=$(dirname "$0")
. "$dir/block-common.sh"
#exec >> /tmp/block-dmmd-`date +%F_%T.%N`.log 2>&1
#echo shell-flags: $-
command=$1
# We check for errors ourselves:
set +e
function run_mdadm()
{
local mdadm_cmd=$1
local msg
local rc
msg="$(/sbin/mdadm $mdadm_cmd 2>&1)"
rc=$?
case "$msg" in
*"has been started"* | *"already active"* )
return 0
;;
*"is already in use"* )
# hmm, might be used by another device in this domU
# leave it to upper layers to detect a real error
return 2
;;
* )
return $rc
;;
esac
return 1
}
function activate_md()
{
# Make it explicitly local
local par=$1
local cfg dev dev_path rc t mdadm_opts
if [ ${par} = ${par%%(*} ]; then
# No configuration file specified
dev=$par
cfg=
else
dev=${par%%(*}
t=${par#*(}
cfg="-c ${t%%)*}"
fi
# Looking for device name or aliase
if [ ${dev:0:1} = / ]; then
dev_path=${dev%/*}
mdadm_opts=
else
dev_path=/dev/md
mdadm_opts="-s -N"
fi
# Is md device already active?
# We need to use full path name, aliase is not possible...
/sbin/mdadm -Q -D $dev_path/${dev##*/} > /dev/null 2>&1 \
&& return 0
run_mdadm "-A $mdadm_opts $dev $cfg"
rc=$?
[ $rc -eq 2 ] && return 0
return $rc
}
function deactivate_md()
{
local par=$1
local dev
if [ ${par} = ${par%%(*} ]; then
# No configuration file specified
dev=${par}
else
dev=${par%%(*}
fi
# Looking for device name or aliase
if [ ${dev:0:1} = / ]; then
dev_path=${dev%/*}
else
dev_path=/dev/md
fi
# We need the device name only while deactivating
/sbin/mdadm -S ${dev_path}/${dev##*/} > /dev/null 2>&1
return $?
}
function activate_lvm()
{
local run_timeout=90
local parsed_timeout
local end_time
# Parse device-create-timeout from /etc/xen/xend-config.sxp
# If not set, use default timeout of 90s
parsed_timeout=$(grep -v "^[ \t]*#.*" /etc/xen/xend-config.sxp \
| sed -n 's/(device-create-timeout \+\([0-9]\+\))/\1/p')
[ ! -z $parsed_timeout ] \
&& run_timeout=$((${parsed_timeout}*9/10))
# First scan for PVs and VGs
# We need this for using md device as PV
/sbin/pvscan > /dev/null 2>&1
# /sbin/vgscan --mknodes > /dev/null 2>&1
end_time=$(($(date +%s)+${run_timeout}))
while true; do
/sbin/lvchange -aey $1 > /dev/null 2>&1
if [ $? -eq 0 -a -e $1 ]; then
return 0
fi
sleep 0.1
if [ $(date +%s) -ge ${end_time} ]; then
log err "Failed to activate $1 within ${run_timeout} seconds"
return 1
fi
done
return 1
}
function deactivate_lvm()
{
/sbin/lvchange -aen $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
# We may have to deactivate the VG now, but can ignore errors:
# /sbin/vgchange -an ${1%/*} || :
# Maybe we need to cleanup the LVM cache:
# /sbin/vgscan --mknodes || :
return 0
fi
return 1
}
BP=100
SP=$BP
VBD=
declare -a stack
function push()
{
if [ -z "$1" ]; then
return
fi
let "SP -= 1"
stack[$SP]="${1}"
}
function pop()
{
VBD=
if [ "$SP" -eq "$BP" ]; then
return
fi
VBD=${stack[$SP]}
let "SP += 1"
}
function activate_dmmd()
{
case $1 in
md)
activate_md $2
return
;;
lvm)
activate_lvm $2
return
;;
esac
}
function deactivate_dmmd()
{
case "$1" in
md)
deactivate_md $2
return
;;
lvm)
deactivate_lvm $2
return
;;
esac
}
function cleanup_stack()
{
while [ 1 ]; do
pop
if [ -z "$VBD" ]; then
break
fi
deactivate_dmmd $VBD
done
}
function parse_par()
{
local ac par rc s t # Make these explicitly local vars
ac=$1
par="$2"
par="$par;"
while [ 1 ]; do
t=${par%%;*}
if [ -z "$t" ]; then
return 0
fi
par=${par#*;}
s=${par%%;*}
if [ -z "$s" ]; then
return 1
fi
par=${par#*;}
if [ "$ac" = "activate" ]; then
activate_dmmd $t $s
rc=$?
if [ $rc -ne 0 ]; then
return 1
fi
fi
push "$t $s"
done
}
case "$command" in
add)
p=`xenstore-read $XENBUS_PATH/params` || true
claim_lock "dmmd"
dmmd=$p
parse_par activate "$dmmd"
rc=$?
if [ $rc -ne 0 ]; then
cleanup_stack
release_lock "dmmd"
exit 1
fi
lastparam=${dmmd##*;}
usedevice=${lastparam%(*}
xenstore-write $XENBUS_PATH/node "$usedevice"
write_dev "$usedevice"
release_lock "dmmd"
exit 0
;;
remove)
p=`xenstore-read $XENBUS_PATH/params` || true
claim_lock "dmmd"
dmmd=$p
parse_par noactivate "$dmmd"
cleanup_stack
release_lock "dmmd"
exit 0
;;
esac
++++++ block-iscsi ++++++
#!/bin/bash
# Usage: block-iscsi [add tgtname | remove dev]
#
# This assumes you're running a correctly configured
# iscsi target (server) at the other end!
# Note that we assume that the passwords for discovery (if needed)
# are in /etc/iscsid.conf
# and the node session passwords (if required) in the
# open-iscsi database below /var/lib/open-iscsi/node.db
#
# (c) Kurt Garloff , 2006-09-04, GNU GPL
# Contributors: Jim Fehlig
# Stefan de Konink
dir=$(dirname "$0")
. "$dir/block-common.sh"
# echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node"
find_sdev()
{
unset dev
for session in /sys/class/iscsi_session/session*; do
if [ "$1" = "`cat $session/targetname 2>/dev/null`" ]; then
dev=`basename $session/device/target*/*:0:*/block*/*`
return
fi
done
}
find_sdev_rev()
{
unset tgt
for session in /sys/class/iscsi_session/session*; do
dev=`basename $session/device/target*/*:0:*/block*/*`
if [ "$dev" = "$1" ]; then
tgt=`cat $session/targetname 2>/dev/null`
return
fi
done
}
case "$command" in
add)
# load modules and start iscsid
/etc/init.d/open-iscsi status >/dev/null 2>&1 ||
{ /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; }
par=`xenstore-read $XENBUS_PATH/params` || true
TGTID=`echo $par | sed "s/\/\///g"`
while read rec uuid; do
if [ "$uuid" = "$TGTID" ]; then
find_sdev $TGTID
if [ -z "$dev" ]; then
/sbin/iscsiadm -m node -T $uuid -p $rec --login || exit 2
sleep 4
find_sdev $TGTID
fi
xenstore-write $XENBUS_PATH/node /dev/$dev
write_dev /dev/$dev
exit 0
fi
done < <(/sbin/iscsiadm -m node)
exit 1
;;
remove)
node=`xenstore-read $XENBUS_PATH/node` || true
dev=$node; dev=${dev#/dev/}
find_sdev_rev $dev
if [ -x /sbin/blockdev -a -n "$node" ]; then blockdev --flushbufs "$node"; fi
test -z "$tgt" && exit 2
/sbin/iscsiadm -m node -T $tgt --logout
exit 1
;;
esac
++++++ block-nbd ++++++
#!/bin/sh
# Usage: block-nbd [bind server ctl_port |unbind node]
#
# The node argument to unbind is the name of the device node we are to
# unbind.
#
# This assumes you're running a correctly configured server at the other end!
dir=$(dirname "$0")
. "$dir/block-common.sh"
#set -x
par=`xenstore-read $XENBUS_PATH/params` || true
#echo $par
case "$command" in
add)
modprobe nbd
for dev in /dev/nbd*; do
if nbd-client $par $dev; then
xenstore-write $XENBUS_PATH/node $dev
write_dev $dev
exit 0
fi
done
exit 1
;;
remove)
node=`xenstore-read $XENBUS_PATH/node` || true
nbd-client -d $node
exit 0
;;
esac
++++++ block-npiv ++++++
#!/bin/bash
# Usage: block-npiv [add npiv | remove dev]
dir=$(dirname "$0")
. "$dir/block-npiv-common.sh"
. "$dir/block-common.sh"
#set -x
#command=$1
case "$command" in
add)
# Params is one big arg, with fields separated by hyphens:
# single path:
# VPWWPN-TGTWWPN-LUN#
# multipath:
# {VPWWPN1.VPWWPN2....VPWWPNx}-{TGTWWPN1.TGTWWPN2....TGTWWPNx}-LUN#
# arg 1 - VPORT's WWPN
# arg 2 - Target's WWPN
# arg 3 - LUN # on Target
# no wwn contains a leading 0x - it is a 16 character hex value
# You may want to optionally pick a specific adapter ?
par=`xenstore-read $XENBUS_PATH/params` || true
NPIVARGS=(${par//-/ })
wc=${#NPIVARGS[@]}
if [ $wc -eq 5 ]; then
# support old syntax
# FABRIC-VPWWPN-VPWWNN-TGTWWPN-LUN
VPORTWWPNS=${NPIVARGS[1]}
VPORTWWNNS=${NPIVARGS[2]}
TGTWWPNS=${NPIVARGS[3]}
LUN=${NPIVARGS[4]}
elif [ $wc -eq 3 ]; then
# new syntax
VPORTWWPNS=${NPIVARGS[0]}
TGTWWPNS=${NPIVARGS[1]}
LUN=${NPIVARGS[2]}
else
# wrong syntax
exit 1
fi
# Ensure we compare everything using lower-case hex characters
TGTWWPNS=`echo $TGTWWPNS | tr A-Z a-z |sed 's/[{.}]/ /g'`
VPORTWWPNS=`echo $VPORTWWPNS | tr A-Z a-z |sed 's/[{.}]/ /g'`
# Only one VPWWNN is supported
VPORTWWNN=`echo $VPORTWWNNS | tr A-Z a-z | sed -e 's/\..*//g' -e 's/{//'`
claim_lock "npiv"
paths=0
for VPORTWWPN in $VPORTWWPNS; do
find_vhost $VPORTWWPN
if test -z "$vhost" ; then
create_vport $VPORTWWPN $VPORTWWNN
if [ $? -ne 0 ] ; then exit 2; fi
sleep 8
find_vhost $VPORTWWPN
if test -z "$vhost" ; then exit 3; fi
fi
for TGTWWPN in $TGTWWPNS; do
find_sdev $vhost $TGTWWPN $LUN
if test -z "$dev"; then
echo "- - -" > /sys/class/scsi_host/$vhost/scan
sleep 2
find_sdev $vhost $TGTWWPN $LUN
fi
if test -z "$dev"; then
exit 4
fi
paths=$(($paths+1))
done
done
release_lock "npiv"
if test $paths -gt 1; then
xenstore-write $XENBUS_PATH/multipath 1
/etc/init.d/multipathd start
if test $? -ne 0 ; then exit 4; fi
dm=`multipath -l /dev/$dev | grep dm | cut -f2 -d' '`
else
xenstore-write $XENBUS_PATH/multipath 0
dm=$dev
fi
if test ! -z "$dm"; then
xenstore-write $XENBUS_PATH/node /dev/$dm
write_dev /dev/$dm
exit 0
fi
exit 4
;;
remove)
node=`xenstore-read $XENBUS_PATH/node` || true
multipath=`xenstore-read $XENBUS_PATH/multipath` || true
# this is really screwy. the first delete of a lun will
# terminate the entire vport (all luns)
if test $multipath = 1; then
par=`xenstore-read $XENBUS_PATH/params` || true
NPIVARGS=(${par//-/ })
wc=${#NPIVARGS[@]}
if [ $wc -eq 5 ]; then
# old syntax
# FABRIC-VPWWPN-VPWWNN-TGTWWPN-LUN
VPORTWWPNS=${NPIVARGS[1]}
elif [ $wc -eq 3 ]; then
# new syntax
VPORTWWPNS=${NPIVARGS[0]}
fi
VPORTWWPNS=`echo $VPORTWWPNS | tr A-Z a-z |sed 's/[{.}]/ /g'`
for VPORTWWPN in $VPORTWWPNS; do
find_vhost $VPORTWWPN
if test -z "$vhost" ; then exit 5; fi
flush_nodes_on_vhost $vhost
delete_vhost $vhost
done
else
dev=$node; dev=${dev#/dev/}
find_vhost_from_dev $dev
if test -z "$vhost" ; then exit 5; fi
flush_nodes_on_vhost $vhost
delete_vhost $vhost
fi
exit 0
;;
esac
++++++ block-npiv-common.sh ++++++
# Look for the NPIV vport with the WWPN
# $1 contains the WWPN (assumes it does not contain a leading "0x")
find_vhost()
{
unset vhost
# look in upstream locations
for fchost in /sys/class/fc_vports/* ; do
if test -e $fchost/port_name ; then
wwpn=`cat $fchost/port_name | sed -e s/^0x//`
if test $wwpn = $1 ; then
# Note: makes the assumption the vport will always have an scsi_host child
vhost=`ls -d $fchost/device/host*`
vhost=`basename $vhost`
return
fi
fi
done
# look in vendor-specific locations
# Emulex - just looks like another scsi_host - so look at fc_hosts...
for fchost in /sys/class/fc_host/* ; do
if test -e $fchost/port_name ; then
wwpn=`cat $fchost/port_name | sed -e s/^0x//`
if test $wwpn = $1 ; then
# Note: makes the assumption the vport will always have an scsi_host child
vhost=`basename $fchost`
return
fi
fi
done
}
# Create a NPIV vport with WWPN
# $1 contains the VPORT WWPN
# $2 may contain the VPORT WWNN
# (assumes no name contains a leading "0x")
create_vport()
{
wwpn=$1
wwnn=$2
if [ -z "$wwnn" ]; then
# auto generate wwnn, follow FluidLabUpdateForEmulex.pdf
# Novell specific identifier
# byte 6 = 0 indicates WWNN, = 1 indicates WWPN
wwnn=${wwpn:0:6}"0"${wwpn:7}
fi
# find a base adapter with npiv support that is on the right fabric
# Look via upstream interfaces
for fchost in /sys/class/fc_host/* ; do
if test -e $fchost/vport_create ; then
# is the link up, w/ NPIV support ?
pstate=`cat $fchost/port_state`
ptype=`cat $fchost/port_type | cut -c 1-5`
if [ $pstate = "Online" -a $ptype = "NPort" ] ; then
vmax=`cat $fchost/max_npiv_vports`
vinuse=`cat $fchost/npiv_vports_inuse`
avail=`expr $vmax - $vinuse`
if [ $avail -gt 0 ] ; then
# create the vport
echo $wwpn":"$wwnn > $fchost/vport_create
if [ $? -eq 0 ] ; then
return 0
fi
# failed - so we'll just look for the next adapter
fi
fi
fi
done
# Look in vendor-specific locations
# Emulex: interfaces mirror upstream, but are under adapter scsi_host
for shost in /sys/class/scsi_host/* ; do
if [ -e $shost/vport_create ] ; then
fchost=`ls -d $shost/device/fc_host*`
# is the link up, w/ NPIV support ?
if [ -e $fchost/port_state ] ; then
pstate=`cat $fchost/port_state`
ptype=`cat $fchost/port_type | cut -c 1-5`
if [ $pstate = "Online" -a $ptype = "NPort" ] ; then
vmax=`cat $shost/max_npiv_vports`
vinuse=`cat $shost/npiv_vports_inuse`
avail=`expr $vmax - $vinuse`
if [ $avail -gt 0 ] ; then
# create the vport
echo $wwpn":"$wwnn > $shost/vport_create
if [ $? -eq 0 ] ; then
return 0
fi
# failed - so we'll just look for the next adapter
fi
fi
fi
fi
done
# BFA are under adapter scsi_host
for shost in /sys/class/scsi_host/* ; do
if [ -e $shost/vport_create ] ; then
fchost=`ls -d $shost/device/fc_host/*`
# is the link up, w/ NPIV support ?
if [ -e $fchost/port_state ] ; then
pstate=`cat $fchost/port_state`
ptype=`cat $fchost/port_type | cut -c 1-5`
if [ $pstate = "Online" -a $ptype = "NPort" ] ; then
# create the vport
echo $wwpn":"$wwnn > $shost/vport_create
if [ $? -eq 0 ] ; then
return 0
fi
# failed - so we'll just look for the next adapter
fi
fi
fi
done
return 1
}
# Look for the LUN on the indicated scsi_host (which is an NPIV vport)
# $1 is the scsi_host name (normalized to simply the hostX name)
# $2 is the WWPN of the tgt port the lun is on
# Note: this implies we don't support a multipath'd lun, or we
# are explicitly identifying a "path"
# $3 is the LUN number of the scsi device
find_sdev()
{
unset dev
hostno=${1/*host/}
for sdev in /sys/class/scsi_device/${hostno}:*:$3 ; do
if test -e $sdev/device/../fc_trans*/target${hostno}*/port_name ; then
tgtwwpn=`cat $sdev/device/../fc_trans*/target${hostno}*/port_name | sed -e s/^0x//`
if test $tgtwwpn = $2 ; then
if test -e $sdev/device/block* ; then
dev=`ls $sdev/device/block*`
dev=${dev##*/}
return
fi
fi
fi
done
}
# Look for the NPIV vhost based on a scsi "sdX" name
# $1 is the "sdX" name
find_vhost_from_dev()
{
unset vhost
hostno=`readlink /sys/block/$1/device`
hostno=${hostno##*/}
hostno=${hostno%%:*}
if test -z "$hostno" ; then return; fi
vhost="host"$hostno
}
# We're about to terminate a vhost based on a scsi device
# Flush all nodes on that vhost as they are about to go away
# $1 is the vhost
flush_nodes_on_vhost()
{
if test ! -x /sbin/blockdev ; then return; fi
hostno=${1/*host/}
for sdev in /sys/class/scsi_device/${hostno}:* ; do
if test -e $sdev/device/block* ; then
dev=`ls $sdev/device/block*`
dev="/dev/"$dev
if test -n "$dev"; then
blockdev --flushbufs $dev
fi
fi
done
}
# Terminate a NPIV vhost
# $1 is vhost
delete_vhost()
{
# use upstream interface
for vport in /sys/class/fc_vports/* ; do
if test -e $vport/device/$1 ; then
if test -e $vport/vport_delete ; then
echo "1" > $vport/vport_delete
if test $? -ne 0 ; then exit 6; fi
sleep 4
return
fi
fi
done
# use vendor specific interface
# Emulex
if test -e /sys/class/fc_host/$1/device/../scsi_host*/lpfc_drvr_version ; then
shost=`ls -1d /sys/class/fc_host/$1/device/../scsi_host* | sed s/.*scsi_host://`
vportwwpn=`cat /sys/class/fc_host/$1/port_name | sed s/^0x//`
vportwwnn=`cat /sys/class/fc_host/$1/node_name | sed s/^0x//`
echo "$vportwwpn:$vportwwnn" > /sys/class/scsi_host/$shost/vport_delete
if test $? -ne 0 ; then exit 6; fi
sleep 4
return
fi
# Qlogic
if test -e /sys/class/fc_host/$1/device/../scsi_host*/driver_version ; then
shost=`ls -1d /sys/class/fc_host/$1/device/../scsi_host* | sed s/.*scsi_host://`
vportwwpn=`cat /sys/class/fc_host/$1/port_name | sed s/^0x//`
vportwwnn=`cat /sys/class/fc_host/$1/node_name | sed s/^0x//`
echo "$vportwwpn:$vportwwnn" > /sys/class/scsi_host/$shost/vport_delete
if test $? -ne 0 ; then exit 6; fi
sleep 4
return
fi
# BFA
if test -e /sys/class/fc_host/$1/device/../scsi_host/*/driver_name ; then
shost=`ls -1d /sys/class/fc_host/$1/device/../scsi_host/* | sed s#.*scsi_host/##`
vportwwpn=`cat /sys/class/fc_host/$1/port_name | sed s/^0x//`
vportwwnn=`cat /sys/class/fc_host/$1/node_name | sed s/^0x//`
echo "$vportwwpn:$vportwwnn" > /sys/class/scsi_host/$shost/vport_delete
if test $? -ne 0 ; then exit 6; fi
sleep 4
return
fi
exit 6
}
vport_status()
{
# Look via upstream interfaces
for fchost in /sys/class/fc_host/* ; do
if test -e $fchost/vport_create ; then
vport_status_display $fchost $fchost
fi
done
# Look in vendor-specific locations
# Emulex: interfaces mirror upstream, but are under adapter scsi_host
for shost in /sys/class/scsi_host/* ; do
if [ -e $shost/vport_create ] ; then
fchost=`ls -d $shost/device/fc_host*`
vport_status_display $fchost $shost
fi
done
return 0
}
vport_status_display()
{
echo
echo "fc_host: " $2
echo "port_state: " `cat $1/port_state`
echo "port_type: " `cat $1/port_type`
echo "fabric_name: " `cat $1/fabric_name`
echo "max_npiv_vports: " `cat $2/max_npiv_vports`
echo "npiv_vports_inuse: " `cat $2/npiv_vports_inuse`
echo "modeldesc: " `cat $2/modeldesc`
echo "speed: " `cat $1/speed`
return 0
}
++++++ block-npiv-vport ++++++
#!/bin/bash
# Usage: block-npiv-vport [create npivargs | delete vportwwpn | status]
dir=$(dirname "$0")
. "$dir/block-npiv-common.sh"
#set -x
command=$1
params=$2
case "$command" in
create)
# Params is one big arg, with fields separated by hyphens:
# FABRIC-VPWWPN-VPWWNN-TGTWWPN-LUN#
# arg 2 - Fabric Name
# arg 3 - VPORT's WWPN
# arg 4 - VPORT's WWNN
# arg 5 - Target's WWPN
# arg 6 - LUN # on Target
# no wwn contains a leading 0x - it is a 16 character hex value
# You may want to optionally pick a specific adapter ?
NPIVARGS=$params;
LUN=${NPIVARGS##*-*-*-*-}; NPIVARGS=${NPIVARGS%-*}
if test $LUN = $NPIVARGS ; then exit 1; fi
TGTWWPN=${NPIVARGS##*-*-*-}; NPIVARGS=${NPIVARGS%-*}
if test $TGTWWPN = $NPIVARGS ; then exit 1; fi
VPORTWWNN=${NPIVARGS##*-*-}; NPIVARGS=${NPIVARGS%-*}
if test $VPORTWWNN = $NPIVARGS ; then exit 1; fi
VPORTWWPN=${NPIVARGS##*-}; NPIVARGS=${NPIVARGS%-*}
if test $VPORTWWPN = $NPIVARGS ; then exit 1; fi
FABRICNM=$NPIVARGS
# Ensure we compare everything using lower-case hex characters
TGTWWPN=`echo $TGTWWPN | tr A-Z a-z`
VPORTWWPN=`echo $VPORTWWPN | tr A-Z a-z`
VPORTWWNN=`echo $VPORTWWNN | tr A-Z a-z`
FABRICNM=`echo $FABRICNM | tr A-Z a-z`
find_vhost $VPORTWWPN $FABRICNM
if test -z "$vhost" ; then
create_vport $FABRICNM $VPORTWWPN $VPORTWWNN
if [ $? -ne 0 ] ; then exit 2; fi
sleep 8
find_vhost $VPORTWWPN $FABRICNM
if test -z "$vhost" ; then exit 3; fi
fi
exit 0
;;
delete)
# Params is VPORT's WWPN
# no wwn contains a leading 0x - it is a 16 character hex value
VPORTWWPN=$params
# Ensure we compare everything using lower-case hex characters
VPORTWWPN=`echo $VPORTWWPN | tr A-Z a-z`
find_vhost $VPORTWWPN $FABRICNM
if test -z "$vhost" ; then exit 4; fi
delete_vhost $vhost
exit 0
;;
status)
vport_status
exit 0
;;
*)
echo "Usage: block-npiv-vport [create npivargs | delete vportwwpn | status]"
exit 1
;;
esac
++++++ boot.local.xenU ++++++
#! /bin/sh
#
# Copyright (c) 2014 SUSE GmbH Nuernberg, Germany. All rights reserved.
#
# Author: Werner Fink , 1996
# Burchard Steinbild , 1996
#
# /etc/init.d/boot.local
#
# script with local commands to be executed from init on system startup
#
#
# Here you should add things, that should happen directly after booting
# before we're going to the first run level.
#
date
# echo "$MACHINE: running $0 $*"
my_REDIRECT="$(echo $REDIRECT | sed 's#^/dev/##')"
my_DEVICE="$(echo $my_REDIRECT | sed 's#^tty##')"
my_SPEED="$(stty speed)"
# echo REDIRECT $REDIRECT $my_REDIRECT
# echo my_DEVICE $my_DEVICE
# echo my_SPEED $my_SPEED
# compose a line like that for inittab
# S0:12345:respawn:/sbin/agetty -L 9600 ttyS0 vt102
case $my_REDIRECT in
ttyS*)
echo adding this line to inittab
echo "$my_DEVICE:12345:respawn:/sbin/agetty -L $my_SPEED $my_REDIRECT vt102"
echo "$my_DEVICE:12345:respawn:/sbin/agetty -L $my_SPEED $my_REDIRECT vt102" >> /etc/inittab
echo $my_REDIRECT >> /etc/securetty
;;
hvc*)
echo adding this line to inittab
echo "$my_DEVICE:12345:respawn:/sbin/agetty -L $my_SPEED $my_REDIRECT vt320"
echo "$my_DEVICE:12345:respawn:/sbin/agetty -L $my_SPEED $my_REDIRECT vt320" >> /etc/inittab
echo $my_REDIRECT >> /etc/securetty
;;
*)
echo "no modification in inittab needed for: $my_REDIRECT"
;;
esac
telinit q
# Changes for Xen
test -f /lib/modules/`uname -r`/modules.dep || depmod -ae
CMDLINE=`cat /proc/cmdline | grep 'ip='`
if test ! -z "$CMDLINE"; then
OLDIFS=$IFS
IFS=":"
read ip oth mask gw hostname dev dhcp rest < /proc/cmdline
IFS=$OLDIFS
hostname $hostname
ip=`echo $ip | sed 's/ip= *//'`
if test ! -z "$ip"; then
if test -z "$mask"; then
if [ ${ip%/*} = $ip ]; then
ip="$ip/27"
fi
echo "ip addr add $ip dev $dev"
ip addr add $ip dev $dev
ip link set $dev up
else
ifconfig add $ip netmask $mask $dev
fi
fi
if test "${dhcp#dhcp}" != "$dhcp"; then
ifup-dhcp $dev
fi
fi
++++++ boot.xen ++++++
#! /bin/sh
# Copyright (c) 2005-2006 SUSE Linux AG, Nuernberg, Germany.
# All rights reserved.
#
# /etc/init.d/boot.xen
#
# LSB compatible service control script; see http://www.linuxbase.org/spec/
#
### BEGIN INIT INFO
# Provides: Xen
# Required-Start: boot.localfs
# Should-Start: boot.localnet
# Required-Stop: boot.localfs
# Should-Stop:
# Default-Start: B
# Default-Stop:
# Short-Description: Switch on and off TLS depending on whether Xen is running
# Description: Xen gets a major performance hit by the way
# recent glibc (& gcc) set up the TLS offset, as it needs to
# play segmentation tricks. This can be avoided by moving away
# the tls libs.
### END INIT INFO
. /etc/rc.status
# Reset status of this service
rc_reset
case "$1" in
start)
echo -n "Starting Xen setup "
if test -d /proc/xen; then
export LD_ASSUME_KERNEL=2.4.21
echo -n "Xen running "
fi
if test -d /proc/xen -a -d /lib/tls; then
echo -n "move /lib/tls away "
mv /lib/tls /lib/tls.save
elif test ! -d /proc/xen -a -d /lib/tls.save; then
echo -n "move back /lib/tls "
mv /lib/tls.save /lib/tls
fi
rc_status -v
;;
stop)
# rc_status -v
;;
try-restart|condrestart)
$0 restart
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 start
# Remember status and be quiet
rc_status
;;
force-reload)
$0 try-restart
rc_status
;;
reload)
rc_failed 3
rc_status -v
;;
status)
echo -n "Checking for Xen "
# Return value is slightly different for the status command:
# 0 - service up and running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running (unused)
# 4 - service status unknown :-(
# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
if test -d /proc/xen; then
if test -d /lib/tls; then
echo -n "Xen running, /lib/tls existing "
rc_failed 1
else
echo -n "Xen running, /lib/tls not existing "
fi
else
if test -d /lib/tls.save; then
echo -n "Xen not running, /lib/tls existing "
rc_failed 2
else
echo -n "Xen not running, /lib/tls not existing "
rc_failed 3
fi
fi
rc_status -v
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}"
exit 1
;;
esac
rc_exit
++++++ bridge-bonding.patch ++++++
Index: xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
===================================================================
--- xen-4.2.0-testing.orig/tools/hotplug/Linux/network-bridge
+++ xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
@@ -251,6 +251,9 @@ op_start () {
claim_lock "network-bridge"
+ local bonded=""
+ [ -e /sys/class/net/${netdev}/bonding ] && bonded="yes"
+
vlans=$(find_active_vlans "${netdev}")
for vlan in $vlans ; do ifdown $vlan ; done
@@ -268,18 +271,32 @@ op_start () {
ip link set ${netdev} down
ip addr flush ${netdev}
fi
- ip link set ${netdev} name ${pdev}
- ip link set ${tdev} name ${bridge}
-
- setup_physical_bridge_port ${pdev}
- # Restore slaves
- if [ -n "${slaves}" ]; then
- ip link set ${pdev} up
- ifenslave ${pdev} ${slaves}
+ if [ "x${bonded}" = "xyes" ]
+ then
+ ip link set ${tdev} name ${bridge}
+ ln -sf /etc/sysconfig/network/ifcfg-${netdev} /etc/sysconfig/network/ifcfg-${pdev}
+ ifup ${pdev}
+ local gw=`ip route show dev ${pdev} | fgrep default | sed 's/default via //'`
+ ip addr flush ${pdev}
+ rm -f /etc/sysconfig/network/ifcfg-${pdev}
+ brctl addif ${bridge} ${pdev}
+ ip link set ${bridge} up
+ [ -n "$gw" ] && ip route add default via ${gw}
+ else
+ ip link set ${netdev} name ${pdev}
+ ip link set ${tdev} name ${bridge}
+
+ _setup_bridge_port ${pdev}
+
+ # Restore slaves
+ if [ -n "${slaves}" ]; then
+ ip link set ${pdev} up
+ ifenslave ${pdev} ${slaves}
+ fi
+ add_to_bridge2 ${bridge} ${pdev}
+ do_ifup ${bridge}
fi
- add_to_bridge2 ${bridge} ${pdev}
- do_ifup ${bridge}
for vlan in $vlans ; do ifup $vlan ; done
++++++ bridge-opensuse.patch ++++++
Index: xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
===================================================================
--- xen-4.2.0-testing.orig/tools/hotplug/Linux/network-bridge
+++ xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
@@ -280,19 +280,19 @@ op_stop () {
transfer_addrs ${bridge} ${pdev}
if ! ifdown ${bridge}; then
get_ip_info ${bridge}
- fi
- ip link set ${pdev} down
- ip addr flush ${bridge}
+ ip link set ${pdev} down
+ ip addr flush ${bridge}
- brctl delif ${bridge} ${pdev}
- ip link set ${bridge} down
+ brctl delif ${bridge} ${pdev}
+ ip link set ${bridge} down
- ip link set ${bridge} name ${tdev}
+ ip link set ${bridge} name ${tdev}
+ brctl delbr ${tdev}
+ fi
+ ip link set ${pdev} down
ip link set ${pdev} name ${netdev}
do_ifup ${netdev}
- brctl delbr ${tdev}
-
release_lock "network-bridge"
}
++++++ bridge-record-creation.patch ++++++
Index: xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
===================================================================
--- xen-4.2.0-testing.orig/tools/hotplug/Linux/network-bridge
+++ xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
@@ -259,6 +259,11 @@ op_start () {
create_bridge ${tdev}
+ # Record creation of bridge in /dev/.sysconfig/network/xenbridges so other
+ # tools, e.g. yast2 lan, know that Xen bridging is active.
+ [ -d /dev/.sysconfig/network/xenbridges ] || mkdir /dev/.sysconfig/network/xenbridges
+ touch /dev/.sysconfig/network/xenbridges/${bridge}
+
preiftransfer ${netdev}
transfer_addrs ${netdev} ${tdev}
# Remember slaves for bonding interface.
@@ -340,6 +345,13 @@ op_stop () {
ip link set ${pdev} name ${netdev}
do_ifup ${netdev}
+ # Remove record of bridge from /dev/.sysconfig/network/xenbridges ...
+ rm -f /dev/.sysconfig/network/xenbridges/${bridge}
+ # ... and directory itself if empty
+ if [ -z "$(ls -A /dev/.sysconfig/network/xenbridges 2>/dev/null)" ]; then
+ rmdir /dev/.sysconfig/network/xenbridges
+ fi
+
for vlan in $vlans ; do ifup $vlan ; done
release_lock "network-bridge"
++++++ bridge-vlan.patch ++++++
Index: xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
===================================================================
--- xen-4.2.0-testing.orig/tools/hotplug/Linux/network-bridge
+++ xen-4.2.0-testing/tools/hotplug/Linux/network-bridge
@@ -195,6 +195,28 @@ antispoofing () {
iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT
}
+find_active_vlans() {
+ local netdev=$1
+ local vlan
+ local vlans
+ vlans=""
+ for vifcfg in /etc/sysconfig/network/ifcfg-vlan* ; do
+ vlan=${vifcfg/*\/ifcfg-}
+ if [ "$vlan" = "vlan*" ]; then
+ continue
+ fi
+ . $vifcfg
+ etherdevice="$ETHERDEVICE"
+ if [ -x /sbin/getcfg-interface ]; then
+ etherdevice=$(/sbin/getcfg-interface "$ETHERDEVICE")
+ fi
+ if [ "$ETHERDEVICE" = "$netdev" ] || [ "$etherdevice" = "$netdev" ] ; then
+ link_exists "$vlan" && vlans="$vlans $vlan"
+ fi
+ done
+ echo "$vlans"
+}
+
# Usage: show_status dev bridge
# Print ifconfig and routes.
show_status () {
@@ -229,6 +251,9 @@ op_start () {
claim_lock "network-bridge"
+ vlans=$(find_active_vlans "${netdev}")
+ for vlan in $vlans ; do ifdown $vlan ; done
+
create_bridge ${tdev}
preiftransfer ${netdev}
@@ -256,6 +281,8 @@ op_start () {
add_to_bridge2 ${bridge} ${pdev}
do_ifup ${bridge}
+ for vlan in $vlans ; do ifup $vlan ; done
+
if [ ${antispoof} = 'yes' ] ; then
antispoofing
fi
@@ -277,6 +304,9 @@ op_stop () {
claim_lock "network-bridge"
+ vlans=$(find_active_vlans "${netdev}")
+ for vlan in $vlans ; do ifdown $vlan ; done
+
transfer_addrs ${bridge} ${pdev}
if ! ifdown ${bridge}; then
get_ip_info ${bridge}
@@ -293,6 +323,8 @@ op_stop () {
ip link set ${pdev} name ${netdev}
do_ifup ${netdev}
+ for vlan in $vlans ; do ifup $vlan ; done
+
release_lock "network-bridge"
}
++++++ build-tapdisk-ioemu.patch ++++++
From f1ebeae7802a5775422004f62630c42e46dcf664 Mon Sep 17 00:00:00 2001
From: Kevin Wolf
Date: Tue, 10 Mar 2009 16:32:40 +0100
Subject: [PATCH 3/6] ioemu: Build tapdisk-ioemu binary
When changing away from the old ioemu, changes in the Makefiles
resulted in tapdisk-ioemu appearing there, but actually not
being built. This patch re-enables the build of tapdisk-ioemu.
Signed-off-by: Kevin Wolf
---
Makefile | 22 +++++++++++++++-------
configure | 2 +-
qemu-tool.c | 2 +-
tapdisk-ioemu.c | 17 -----------------
4 files changed, 17 insertions(+), 26 deletions(-)
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/Makefile
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/Makefile
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/Makefile
@@ -46,14 +46,6 @@ $(filter %-user,$(SUBDIR_RULES)): libqem
recurse-all: $(SUBDIR_RULES)
-CPPFLAGS += -I$(XEN_ROOT)/tools/libxc
-CPPFLAGS += -I$(XEN_ROOT)/tools/blktap/lib
-CPPFLAGS += -I$(XEN_ROOT)/tools/xenstore
-CPPFLAGS += -I$(XEN_ROOT)/tools/include
-
-tapdisk-ioemu: tapdisk-ioemu.c cutils.c block.c block-raw.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c block-dmg.c block-bochs.c block-vpc.c block-vvfat.c block-qcow2.c hw/xen_blktap.c osdep.c
- $(CC) -DQEMU_TOOL $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) $(LDFLAGS) $(BASE_LDFLAGS) -o $@ $^ -lz $(LIBS)
-
#######################################################################
# BLOCK_OBJS is code used by both qemu system emulation and qemu-img
@@ -72,6 +64,21 @@ endif
BLOCK_OBJS += block-raw-posix.o
endif
+#######################################################################
+# tapdisk-ioemu
+
+hw/tapdisk-xen_blktap.o: hw/xen_blktap.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_IMG -DQEMU_TOOL -c -o $@ $<
+tapdisk-ioemu.o: tapdisk-ioemu.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -DQEMU_IMG -DQEMU_TOOL -c -o $@ $<
+
+tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/libxc
+tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/blktap/lib
+tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/xenstore
+tapdisk-ioemu: CPPFLAGS += -I$(XEN_ROOT)/tools/include
+tapdisk-ioemu: tapdisk-ioemu.o $(BLOCK_OBJS) qemu-tool.o hw/tapdisk-xen_blktap.o
+ $(CC) $(LDFLAGS) -o $@ $^ -lz $(LIBS)
+
######################################################################
# libqemu_common.a: Target independent part of system emulation. The
# long term path is to suppress *all* target specific code in case of
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/configure
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/configure
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/configure
@@ -1512,7 +1512,7 @@ bsd)
;;
esac
-tools=
+tools="tapdisk-ioemu"
if test `expr "$target_list" : ".*softmmu.*"` != 0 ; then
tools="qemu-img\$(EXESUF) $tools"
if [ "$linux" = "yes" ] ; then
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-tool.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/qemu-tool.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-tool.c
@@ -68,7 +68,7 @@ void qemu_bh_delete(QEMUBH *bh)
qemu_free(bh);
}
-int qemu_set_fd_handler2(int fd,
+int __attribute__((weak)) qemu_set_fd_handler2(int fd,
IOCanRWHandler *fd_read_poll,
IOHandler *fd_read,
IOHandler *fd_write,
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
@@ -12,34 +12,12 @@
extern void qemu_aio_init(void);
extern void qemu_aio_poll(void);
-extern void bdrv_init(void);
-
-extern void *qemu_mallocz(size_t size);
-extern void qemu_free(void *ptr);
extern void *fd_start;
int domid = 0;
FILE* logfile;
-void term_printf(const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
-}
-
-void term_print_filename(const char *filename)
-{
- term_printf(filename);
-}
-
-
-typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
-typedef int IOCanRWHandler(void *opaque);
-typedef void IOHandler(void *opaque);
-
typedef struct IOHandlerRecord {
int fd;
IOCanRWHandler *fd_read_poll;
@@ -103,7 +81,6 @@ int main(void)
logfile = stderr;
bdrv_init();
- qemu_aio_init();
init_blktap();
/* Daemonize */
@@ -115,8 +92,6 @@ int main(void)
* completed aio operations.
*/
while (1) {
- qemu_aio_poll();
-
max_fd = -1;
FD_ZERO(&rfds);
for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next)
++++++ capslock_enable.patch ++++++
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
@@ -1329,6 +1329,11 @@ static void do_key_event(VncState *vs, i
}
break;
case 0x3a: /* CapsLock */
+ if(!down){
+ vs->modifiers_state[keycode] ^= 1;
+ kbd_put_keycode(keycode | 0x80);
+ }
+ return;
case 0x45: /* NumLock */
if (down) {
kbd_put_keycode(keycode & 0x7f);
++++++ cdrom-removable.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/server/HalDaemon.py
===================================================================
--- /dev/null
+++ xen-4.4.0-testing/tools/python/xen/xend/server/HalDaemon.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python
+# -*- mode: python; -*-
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2007 Pat Campbell
+# Copyright (C) 2007 Novell Inc.
+#============================================================================
+
+"""hald (Hardware Abstraction Layer Daemon) watcher for Xen management
+ of removable block device media.
+
+"""
+
+import gobject
+import dbus
+import dbus.glib
+import os
+import types
+import sys
+import signal
+import traceback
+from xen.xend.xenstore.xstransact import xstransact, complete
+from xen.xend.xenstore.xsutil import xshandle
+from xen.xend import PrettyPrint
+from xen.xend import XendLogging
+from xen.xend.XendLogging import log
+
+DEVICE_TYPES = ['vbd', 'tap']
+
+class HalDaemon:
+ """The Hald block device watcher for XEN
+ """
+
+ """Default path to the log file. """
+ logfile_default = "/var/log/xen/hald.log"
+
+ """Default level of information to be logged."""
+ loglevel_default = 'INFO'
+
+
+ def __init__(self):
+
+ XendLogging.init(self.logfile_default, self.loglevel_default)
+ log.debug( "%s", "__init__")
+
+ self.udi_dict = {}
+ self.debug = 0
+ self.dbpath = "/local/domain/0/backend"
+ self.bus = dbus.SystemBus()
+ self.hal_manager_obj = self.bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
+ self.hal_manager = dbus.Interface( self.hal_manager_obj, 'org.freedesktop.Hal.Manager')
+ self.gatherBlockDevices()
+ self.registerDeviceCallbacks()
+
+ def run(self):
+ log.debug( "%s", "In new run" );
+ try:
+ self.mainloop = gobject.MainLoop()
+ self.mainloop.run()
+ except KeyboardInterrupt, ex:
+ log.debug('Keyboard exception handler: %s', ex )
+ self.mainloop.quit()
+ except Exception, ex:
+ log.debug('Generic exception handler: %s', ex )
+ self.mainloop.quit()
+
+ def __del__(self):
+ log.debug( "%s", "In del " );
+ self.unRegisterDeviceCallbacks()
+ self.mainloop.quit()
+
+ def shutdown(self):
+ log.debug( "%s", "In shutdown now " );
+ self.unRegisterDeviceCallbacks()
+ self.mainloop.quit()
+
+ def stop(self):
+ log.debug( "%s", "In stop now " );
+ self.unRegisterDeviceCallbacks()
+ self.mainloop.quit()
+
+ def gatherBlockDevices(self):
+
+ # Get all the current devices from hal and save in a dictionary
+ try:
+ device_names = self.hal_manager.GetAllDevices()
+ i = 0;
+ for name in device_names:
+ #log.debug("device name, device=%s",name)
+ dev_obj = self.bus.get_object ('org.freedesktop.Hal', name)
+ dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device')
+ dev_properties = dev_obj.GetAllProperties(dbus_interface="org.freedesktop.Hal.Device")
+ if dev_properties.has_key('block.device'):
+ dev_str = dev_properties['block.device']
+ dev_major = dev_properties['block.major']
+ dev_minor = dev_properties['block.minor']
+ udi_info = {}
+ udi_info['device'] = dev_str
+ udi_info['major'] = dev_major
+ udi_info['minor'] = dev_minor
+ udi_info['udi'] = name
+ self.udi_dict[i] = udi_info
+ i = i + 1
+ except Exception, ex:
+ print >>sys.stderr, 'Exception gathering block devices:', ex
+ log.warn("Exception gathering block devices (%s)",ex)
+
+ #
+ def registerDeviceCallbacks(self):
+ # setup the callbacks for when the gdl changes
+ self.hal_manager.connect_to_signal('DeviceAdded', self.device_added_callback)
+ self.hal_manager.connect_to_signal('DeviceRemoved', self.device_removed_callback)
+
+ #
+ def unRegisterDeviceCallbacks(self):
+ # setup the callbacks for when the gdl changes
+ self.hal_manager.remove_signal_receiver(self.device_added_callback,'DeviceAdded')
+ self.hal_manager.remove_signal_receiver(self.device_removed_callback,'DeviceRemoved')
+
+ #
+ def device_removed_callback(self,udi):
+ log.debug('UDI %s was removed',udi)
+ self.show_dict(self.udi_dict)
+ for key in self.udi_dict:
+ udi_info = self.udi_dict[key]
+ if udi_info['udi'] == udi:
+ device = udi_info['device']
+ major = udi_info['major']
+ minor = udi_info['minor']
+ self.change_xenstore( "remove", device, major, minor)
+
+ # Adds device to dictionary if not already there
+ def device_added_callback(self,udi):
+ log.debug('UDI %s was added', udi)
+ self.show_dict(self.udi_dict)
+ dev_obj = self.bus.get_object ('org.freedesktop.Hal', udi)
+ dev = dbus.Interface (dev_obj, 'org.freedesktop.Hal.Device')
+ device = dev.GetProperty ('block.device')
+ major = dev.GetProperty ('block.major')
+ minor = dev.GetProperty ('block.minor')
+ udi_info = {}
+ udi_info['device'] = device
+ udi_info['major'] = major
+ udi_info['minor'] = minor
+ udi_info['udi'] = udi
+ already = 0
+ cnt = 0;
+ for key in self.udi_dict:
+ info = self.udi_dict[key]
+ if info['udi'] == udi:
+ already = 1
+ break
+ cnt = cnt + 1
+ if already == 0:
+ self.udi_dict[cnt] = udi_info;
+ log.debug('UDI %s was added, device:%s major:%s minor:%s index:%d\n', udi, device, major, minor, cnt)
+ self.change_xenstore( "add", device, major, minor)
+
+ # Debug helper, shows dictionary contents
+ def show_dict(self,dict=None):
+ if self.debug == 0 :
+ return
+ if dict == None :
+ dict = self.udi_dict
+ for key in dict:
+ log.debug('udi_info %s udi_info:%s',key,dict[key])
+
+ # Set or clear xenstore media-present depending on the action argument
+ # for every vbd that has this block device
+ def change_xenstore(self,action, device, major, minor):
+ for type in DEVICE_TYPES:
+ path = self.dbpath + '/' + type
+ domains = xstransact.List(path)
+ log.debug('domains: %s', domains)
+ for domain in domains: # for each domain
+ devices = xstransact.List( path + '/' + domain)
+ log.debug('devices: %s',devices)
+ for device in devices: # for each vbd device
+ str = device.split('/')
+ vbd_type = None;
+ vbd_physical_device = None
+ vbd_media = None
+ vbd_device_path = path + '/' + domain + '/' + device
+ listing = xstransact.List(vbd_device_path)
+ for entry in listing: # for each entry
+ item = path + '/' + entry
+ value = xstransact.Read( vbd_device_path + '/' + entry)
+ log.debug('%s=%s',item,value)
+ if item.find('media-present') != -1:
+ vbd_media = item;
+ vbd_media_path = item
+ if item.find('physical-device') != -1:
+ vbd_physical_device = value;
+ if item.find('type') != -1:
+ vbd_type = value;
+ if vbd_type is not None and vbd_physical_device is not None and vbd_media is not None :
+ inode = vbd_physical_device.split(':')
+ imajor = parse_hex(inode[0])
+ iminor = parse_hex(inode[1])
+ log.debug("action:%s major:%s- minor:%s- imajor:%s- iminor:%s- inode: %s",
+ action,major,minor, imajor, iminor, inode)
+ if int(imajor) == int(major) and int(iminor) == int(minor):
+ if action == "add":
+ xs_dict = {'media': "1"}
+ xstransact.Write(vbd_device_path, 'media-present', "1" )
+ log.debug("wrote xenstore media-present 1 path:%s",vbd_media_path)
+ else:
+ xstransact.Write(vbd_device_path, 'media-present', "0" )
+ log.debug("wrote xenstore media 0 path:%s",vbd_media_path)
+
+def mylog( fmt, *args):
+ f = open('/tmp/haldaemon.log', 'a')
+ print >>f, "HalDaemon ", fmt % args
+ f.close()
+
+
+def parse_hex(val):
+ try:
+ if isinstance(val, types.StringTypes):
+ return int(val, 16)
+ else:
+ return val
+ except ValueError:
+ return None
+
+if __name__ == "__main__":
+ watcher = HalDaemon()
+ watcher.run()
+ print 'Falling off end'
+
+
Index: xen-4.4.0-testing/tools/python/xen/xend/server/Hald.py
===================================================================
--- /dev/null
+++ xen-4.4.0-testing/tools/python/xen/xend/server/Hald.py
@@ -0,0 +1,125 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#============================================================================
+# Copyright (C) 2007 Pat Campbell
+# Copyright (C) 2007 Novell Inc.
+#============================================================================
+
+import errno
+import types
+import os
+import sys
+import time
+import signal
+from traceback import print_exc
+
+from xen.xend.XendLogging import log
+
+class Hald:
+ def __init__(self):
+ self.ready = False
+ self.running = True
+
+ def run(self):
+ """Starts the HalDaemon process
+ """
+ self.ready = True
+ try:
+ myfile = self.find("xen/xend/server/HalDaemon.py")
+ args = (["python", myfile ])
+ self.pid = self.daemonize("python", args )
+ #log.debug( "%s %s pid:%d", "Hald.py starting ", args, self.pid )
+ except:
+ self.pid = -1
+ log.debug("Unable to start HalDaemon process")
+
+ def shutdown(self):
+ """Shutdown the HalDaemon process
+ """
+ log.debug("%s pid:%d", "Hald.shutdown()", self.pid)
+ self.running = False
+ self.ready = False
+ if self.pid != -1:
+ try:
+ os.kill(self.pid, signal.SIGINT)
+ except:
+ print_exc()
+
+ def daemonize(self,prog, args):
+ """Runs a program as a daemon with the list of arguments. Returns the PID
+ of the daemonized program, or returns 0 on error.
+ Copied from xm/create.py instead of importing to reduce coupling
+ """
+ r, w = os.pipe()
+ pid = os.fork()
+
+ if pid == 0:
+ os.close(r)
+ w = os.fdopen(w, 'w')
+ os.setsid()
+ try:
+ pid2 = os.fork()
+ except:
+ pid2 = None
+ if pid2 == 0:
+ os.chdir("/")
+ env = os.environ.copy()
+ env['PYTHONPATH'] = self.getpythonpath()
+ for fd in range(0, 256):
+ try:
+ os.close(fd)
+ except:
+ pass
+ os.open("/dev/null", os.O_RDWR)
+ os.dup2(0, 1)
+ os.dup2(0, 2)
+ os.execvpe(prog, args, env)
+ os._exit(1)
+ else:
+ w.write(str(pid2 or 0))
+ w.close()
+ os._exit(0)
+ os.close(w)
+ r = os.fdopen(r)
+ daemon_pid = int(r.read())
+ r.close()
+ os.waitpid(pid, 0)
+ #log.debug( "daemon_pid: %d", daemon_pid )
+ return daemon_pid
+
+ def getpythonpath(self):
+ str = " "
+ for p in sys.path:
+ if str != " ":
+ str = str + ":" + p
+ else:
+ if str != "":
+ str = p
+ return str
+
+ def find(self,path, matchFunc=os.path.isfile):
+ """Find a module in the sys.path
+ From web page: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52224
+ """
+ for dirname in sys.path:
+ candidate = os.path.join(dirname, path)
+ if matchFunc(candidate):
+ return candidate
+ raise Error("Can't find file %s" % path)
+
+if __name__ == "__main__":
+ watcher = Hald()
+ watcher.run()
+ time.sleep(10)
+ watcher.shutdown()
Index: xen-4.4.0-testing/tools/python/xen/xend/server/SrvServer.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/server/SrvServer.py
+++ xen-4.4.0-testing/tools/python/xen/xend/server/SrvServer.py
@@ -57,6 +57,7 @@ from xen.web.SrvDir import SrvDir
from SrvRoot import SrvRoot
from XMLRPCServer import XMLRPCServer
+from xen.xend.server.Hald import Hald
xoptions = XendOptions.instance()
@@ -252,6 +253,8 @@ def _loadConfig(servers, root, reload):
if xoptions.get_xend_unix_xmlrpc_server():
servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False))
+ servers.add(Hald())
+
def create():
root = SrvDir()
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -18,6 +18,7 @@
#include "exec-all.h"
#include "sysemu.h"
+#include "console.h"
#include "hw.h"
#include "pci.h"
#include "qemu-timer.h"
@@ -604,6 +605,21 @@ void xenstore_parse_domain_config(int hv
#endif
bs = bdrv_new(dev);
+
+ /* if cdrom physical put a watch on media-present */
+ if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
+ if (drv && !strcmp(drv, "phy")) {
+ if (pasprintf(&buf, "%s/media-present", bpath) != -1) {
+ if (bdrv_is_inserted(bs))
+ xs_write(xsh, XBT_NULL, buf, "1", strlen("1"));
+ else {
+ xs_write(xsh, XBT_NULL, buf, "0", strlen("0"));
+ }
+ xs_watch(xsh, buf, "media-present");
+ }
+ }
+ }
+
/* check if it is a cdrom */
if (danger_type && !strcmp(danger_type, "cdrom")) {
bdrv_set_type_hint(bs, BDRV_TYPE_CDROM);
@@ -1095,6 +1111,50 @@ static void xenstore_process_vcpu_set_ev
return;
}
+static void xenstore_process_media_change_event(char **vec)
+{
+ char *media_present = NULL;
+ unsigned int len;
+
+ media_present = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len);
+
+ if (media_present) {
+ BlockDriverState *bs;
+ char *buf = NULL, *cp = NULL, *path = NULL, *dev = NULL;
+
+ path = strdup(vec[XS_WATCH_PATH]);
+ cp = strstr(path, "media-present");
+ if (cp){
+ *(cp-1) = '\0';
+ pasprintf(&buf, "%s/dev", path);
+ dev = xs_read(xsh, XBT_NULL, buf, &len);
+ if (dev) {
+ if ( !strncmp(dev, "xvd", 3)) {
+ memmove(dev, dev+1, strlen(dev));
+ dev[0] = 'h';
+ dev[1] = 'd';
+ }
+ bs = bdrv_find(dev);
+ if (!bs) {
+ term_printf("device not found\n");
+ return;
+ }
+ if (strcmp(media_present, "0") == 0 && bs) {
+ bdrv_close(bs);
+ }
+ else if (strcmp(media_present, "1") == 0 &&
+ bs != NULL && bs->drv == NULL) {
+ if (bdrv_open(bs, bs->filename, 0 /* snapshot */) < 0) {
+ fprintf(logfile, "%s() qemu: could not open cdrom disk '%s'\n",
+ __func__, bs->filename);
+ }
+ bs->media_changed = 1;
+ }
+ }
+ }
+ }
+}
+
void xenstore_process_event(void *opaque)
{
char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL;
@@ -1130,6 +1190,11 @@ void xenstore_process_event(void *opaque
xenstore_watch_callbacks[i].cb(vec[XS_WATCH_TOKEN],
xenstore_watch_callbacks[i].opaque);
+ if (!strcmp(vec[XS_WATCH_TOKEN], "media-present")) {
+ xenstore_process_media_change_event(vec);
+ goto out;
+ }
+
hd_index = drive_name_to_index(vec[XS_WATCH_TOKEN]);
if (hd_index == -1) {
fprintf(stderr,"medium change watch on `%s' -"
++++++ change-vnc-passwd.patch ++++++
Add support of change-vnc-password while vm is running.
Signed-off-by: Chunyan Liu
---
tools/python/xen/xend/XendDomainInfo.py | 14 ++++++++++++++
tools/python/xen/xend/server/XMLRPCServer.py | 2 +-
tools/python/xen/xm/main.py | 12 ++++++++++++
tools/qemu-xen-traditional-dir-remote/vl.c | 2 +-
tools/qemu-xen-traditional-dir-remote/vnc.c | 1 +
tools/qemu-xen-traditional-dir-remote/xenstore.c | 14 ++++++++++++++
6 files changed, 43 insertions(+), 2 deletions(-)
Index: xen-4.4.3-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.3-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1665,6 +1665,20 @@ class XendDomainInfo:
vfb_ctrl.reconfigureDevice(0, dev_info)
break
+ def chgvncpasswd(self, passwd):
+ if self._stateGet() != DOM_STATE_HALTED:
+ path = '/local/domain/0/backend/vfb/%u/0/' % self.getDomid()
+ xstransact.Write(path, 'vncpasswd', passwd)
+ self.image.signalDeviceModel("chgvncpasswd", "vncpasswdchged")
+
+ for dev_uuid, (dev_type, dev_info) in self.info['devices'].items():
+ if dev_type == 'vfb':
+ dev_info['vncpasswd'] = passwd
+ dev_info['other_config']['vncpasswd'] = passwd
+ self.info.device_update(dev_uuid, cfg_xenapi = dev_info)
+ break
+ xen.xend.XendDomain.instance().managed_config_save(self)
+
#
# Function to update xenstore /vm/*
#
Index: xen-4.4.3-testing/tools/python/xen/xend/server/XMLRPCServer.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xend/server/XMLRPCServer.py
+++ xen-4.4.3-testing/tools/python/xen/xend/server/XMLRPCServer.py
@@ -95,7 +95,7 @@ methods = ['device_create', 'device_conf
'destroyDevice','getDeviceSxprs',
'setMemoryTarget', 'setName', 'setVCpuCount', 'shutdown',
'send_sysrq', 'getVCPUInfo', 'waitForDevices',
- 'getRestartCount', 'getBlockDeviceClass']
+ 'getRestartCount', 'getBlockDeviceClass', 'chgvncpasswd']
exclude = ['domain_create', 'domain_restore']
Index: xen-4.4.3-testing/tools/python/xen/xm/main.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xm/main.py
+++ xen-4.4.3-testing/tools/python/xen/xm/main.py
@@ -21,6 +21,7 @@
"""Grand unified management application for Xen.
"""
+import getpass
import atexit
import cmd
import os
@@ -280,6 +281,9 @@ SUBCOMMAND_HELP = {
'getenforce' : ('', 'Returns the current enforcing mode for the Flask XSM module (Enforcing,Permissive)'),
'setenforce' : ('[ (Enforcing|1) | (Permissive|0) ]',
'Modifies the current enforcing mode for the Flask XSM module'),
+ #change vnc password
+ 'change-vnc-passwd' : ('<Domain>',\
+ 'Change vnc password'),
}
SUBCOMMAND_OPTIONS = {
@@ -404,6 +408,7 @@ common_commands = [
"usb-del",
"domstate",
"vcpu-set",
+ "change-vnc-passwd",
]
domain_commands = [
@@ -441,6 +446,7 @@ domain_commands = [
"vcpu-list",
"vcpu-pin",
"vcpu-set",
+ "change-vnc-passwd",
]
host_commands = [
@@ -3751,6 +3757,10 @@ def xm_cpupool_migrate(args):
else:
server.xend.cpu_pool.migrate(domname, poolname)
+def xm_chgvncpasswd(args):
+ arg_check(args, "change-vnc-passwd", 1)
+ pwd = getpass.getpass("Enter new password: ")
+ server.xend.domain.chgvncpasswd(args[0], pwd)
commands = {
"shell": xm_shell,
@@ -3857,6 +3867,8 @@ commands = {
"usb-del": xm_usb_del,
#domstate
"domstate": xm_domstate,
+ #change vnc password:
+ "change-vnc-passwd": xm_chgvncpasswd,
}
## The commands supported by a separate argument parser in xend.xm.
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/vl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/vl.c
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/vl.c
@@ -200,7 +200,7 @@ DriveInfo drives_table[MAX_DRIVES+1];
int nb_drives;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
int vga_ram_size;
-static DisplayState *display_state;
+DisplayState *display_state;
int nographic;
static int curses;
static int sdl;
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
@@ -2607,6 +2607,7 @@ int vnc_display_password(DisplayState *d
if (password && password[0]) {
if (!(vs->password = qemu_strdup(password)))
return -1;
+ vs->auth = VNC_AUTH_VNC;
}
return 0;
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -25,6 +25,7 @@
#include "qemu-xen.h"
#include "xen_backend.h"
+extern DisplayState *display_state;
struct xs_handle *xsh = NULL;
static char *media_filename[MAX_DRIVES+1];
static QEMUTimer *insert_timer = NULL;
@@ -897,6 +898,19 @@ static void xenstore_process_dm_command_
} else if (!strncmp(command, "continue", len)) {
fprintf(logfile, "dm-command: continue after state save\n");
xen_pause_requested = 0;
+ } else if (!strncmp(command, "chgvncpasswd", len)) {
+ fprintf(logfile, "dm-command: change vnc passwd\n");
+ if (pasprintf(&path,
+ "/local/domain/0/backend/vfb/%u/0/vncpasswd", domid) == -1) {
+ fprintf(logfile, "out of memory reading dm command parameter\n");
+ goto out;
+ }
+ par = xs_read(xsh, XBT_NULL, path, &len);
+ if (!par)
+ goto out;
+ if (vnc_display_password(display_state, par) == 0)
+ xenstore_record_dm_state("vncpasswdchged");
+ free(par);
} else if (!strncmp(command, "usb-add", len)) {
fprintf(logfile, "dm-command: usb-add a usb device\n");
if (pasprintf(&path,
++++++ disable-wget-check.patch ++++++
Index: xen-4.4.1-testing/tools/configure
===================================================================
--- xen-4.4.1-testing.orig/tools/configure
+++ xen-4.4.1-testing/tools/configure
@@ -633,9 +633,6 @@ libgcrypt
EXTFS_LIBS
system_aio
zlib
-FETCHER
-FTP
-WGET
glib_LIBS
glib_CFLAGS
PKG_CONFIG_LIBDIR
@@ -7375,104 +7372,104 @@ $as_echo "yes" >&6; }
fi
# Extract the first word of "wget", so it can be a program name with args.
-set dummy wget; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_WGET+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $WGET in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_WGET="$WGET" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_WGET" && ac_cv_path_WGET="no"
- ;;
-esac
-fi
-WGET=$ac_cv_path_WGET
-if test -n "$WGET"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5
-$as_echo "$WGET" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-if test x"$WGET" != x"no"; then :
-
- FETCHER="$WGET -c -O"
-
-else
-
- # Extract the first word of "ftp", so it can be a program name with args.
-set dummy ftp; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_FTP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $FTP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_FTP="$FTP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_FTP="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_FTP" && ac_cv_path_FTP="no"
- ;;
-esac
-fi
-FTP=$ac_cv_path_FTP
-if test -n "$FTP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FTP" >&5
-$as_echo "$FTP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- if test x"$FTP" != x"no"; then :
-
- FETCHER="$FTP -o"
-
-else
-
- as_fn_error $? "cannot find wget or ftp" "$LINENO" 5
-
-fi
-
-fi
+#set dummy wget; ac_word=$2
+#{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+#$as_echo_n "checking for $ac_word... " >&6; }
+#if ${ac_cv_path_WGET+:} false; then :
+# $as_echo_n "(cached) " >&6
+#else
+# case $WGET in
+# [\\/]* | ?:[\\/]*)
+# ac_cv_path_WGET="$WGET" # Let the user override the test with a path.
+# ;;
+# *)
+# as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+#for as_dir in $PATH
+#do
+# IFS=$as_save_IFS
+# test -z "$as_dir" && as_dir=.
+# for ac_exec_ext in '' $ac_executable_extensions; do
+# if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+# ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
+# $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+# break 2
+# fi
+#done
+# done
+#IFS=$as_save_IFS
+#
+# test -z "$ac_cv_path_WGET" && ac_cv_path_WGET="no"
+# ;;
+#esac
+#fi
+#WGET=$ac_cv_path_WGET
+#if test -n "$WGET"; then
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5
+#$as_echo "$WGET" >&6; }
+#else
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+#$as_echo "no" >&6; }
+#fi
+#
+#
+#if test x"$WGET" != x"no"; then :
+#
+# FETCHER="$WGET -c -O"
+#
+#else
+#
+# # Extract the first word of "ftp", so it can be a program name with args.
+#set dummy ftp; ac_word=$2
+#{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+#$as_echo_n "checking for $ac_word... " >&6; }
+#if ${ac_cv_path_FTP+:} false; then :
+# $as_echo_n "(cached) " >&6
+#else
+# case $FTP in
+# [\\/]* | ?:[\\/]*)
+# ac_cv_path_FTP="$FTP" # Let the user override the test with a path.
+# ;;
+# *)
+# as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+#for as_dir in $PATH
+#do
+# IFS=$as_save_IFS
+# test -z "$as_dir" && as_dir=.
+# for ac_exec_ext in '' $ac_executable_extensions; do
+# if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+# ac_cv_path_FTP="$as_dir/$ac_word$ac_exec_ext"
+# $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+# break 2
+# fi
+#done
+# done
+#IFS=$as_save_IFS
+#
+# test -z "$ac_cv_path_FTP" && ac_cv_path_FTP="no"
+# ;;
+#esac
+#fi
+#FTP=$ac_cv_path_FTP
+#if test -n "$FTP"; then
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FTP" >&5
+#$as_echo "$FTP" >&6; }
+#else
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+#$as_echo "no" >&6; }
+#fi
+#
+#
+# if test x"$FTP" != x"no"; then :
+#
+# FETCHER="$FTP -o"
+#
+#else
+#
+# as_fn_error $? "cannot find wget or ftp" "$LINENO" 5
+#
+#fi
+#
+#fi
Index: xen-4.4.1-testing/stubdom/configure
===================================================================
--- xen-4.4.1-testing.orig/stubdom/configure
+++ xen-4.4.1-testing/stubdom/configure
@@ -623,8 +623,6 @@ LDFLAGS
CFLAGS
CC
FETCHER
-FTP
-WGET
CMAKE
extfiles
debug
@@ -2300,104 +2298,104 @@ extfiles=$ax_cv_extfiles
# Extract the first word of "wget", so it can be a program name with args.
-set dummy wget; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_WGET+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $WGET in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_WGET="$WGET" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_WGET" && ac_cv_path_WGET="no"
- ;;
-esac
-fi
-WGET=$ac_cv_path_WGET
-if test -n "$WGET"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5
-$as_echo "$WGET" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-if test x"$WGET" != x"no"; then :
-
- FETCHER="$WGET -c -O"
-
-else
-
- # Extract the first word of "ftp", so it can be a program name with args.
-set dummy ftp; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_FTP+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- case $FTP in
- [\\/]* | ?:[\\/]*)
- ac_cv_path_FTP="$FTP" # Let the user override the test with a path.
- ;;
- *)
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_path_FTP="$as_dir/$ac_word$ac_exec_ext"
- $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
- done
-IFS=$as_save_IFS
-
- test -z "$ac_cv_path_FTP" && ac_cv_path_FTP="no"
- ;;
-esac
-fi
-FTP=$ac_cv_path_FTP
-if test -n "$FTP"; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FTP" >&5
-$as_echo "$FTP" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
- if test x"$FTP" != x"no"; then :
-
- FETCHER="$FTP -o"
-
-else
-
- as_fn_error $? "cannot find wget or ftp" "$LINENO" 5
-
-fi
-
-fi
+#set dummy wget; ac_word=$2
+#{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+#$as_echo_n "checking for $ac_word... " >&6; }
+#if ${ac_cv_path_WGET+:} false; then :
+# $as_echo_n "(cached) " >&6
+#else
+# case $WGET in
+# [\\/]* | ?:[\\/]*)
+# ac_cv_path_WGET="$WGET" # Let the user override the test with a path.
+# ;;
+# *)
+# as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+#for as_dir in $PATH
+#do
+# IFS=$as_save_IFS
+# test -z "$as_dir" && as_dir=.
+# for ac_exec_ext in '' $ac_executable_extensions; do
+# if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+# ac_cv_path_WGET="$as_dir/$ac_word$ac_exec_ext"
+# $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+# break 2
+# fi
+#done
+# done
+#IFS=$as_save_IFS
+#
+# test -z "$ac_cv_path_WGET" && ac_cv_path_WGET="no"
+# ;;
+#esac
+#fi
+#WGET=$ac_cv_path_WGET
+#if test -n "$WGET"; then
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WGET" >&5
+#$as_echo "$WGET" >&6; }
+#else
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+#$as_echo "no" >&6; }
+#fi
+#
+#
+#if test x"$WGET" != x"no"; then :
+#
+# FETCHER="$WGET -c -O"
+#
+#else
+#
+# # Extract the first word of "ftp", so it can be a program name with args.
+#set dummy ftp; ac_word=$2
+#{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+#$as_echo_n "checking for $ac_word... " >&6; }
+#if ${ac_cv_path_FTP+:} false; then :
+# $as_echo_n "(cached) " >&6
+#else
+# case $FTP in
+# [\\/]* | ?:[\\/]*)
+# ac_cv_path_FTP="$FTP" # Let the user override the test with a path.
+# ;;
+# *)
+# as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+#for as_dir in $PATH
+#do
+# IFS=$as_save_IFS
+# test -z "$as_dir" && as_dir=.
+# for ac_exec_ext in '' $ac_executable_extensions; do
+# if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+# ac_cv_path_FTP="$as_dir/$ac_word$ac_exec_ext"
+# $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+# break 2
+# fi
+#done
+# done
+#IFS=$as_save_IFS
+#
+# test -z "$ac_cv_path_FTP" && ac_cv_path_FTP="no"
+# ;;
+#esac
+#fi
+#FTP=$ac_cv_path_FTP
+#if test -n "$FTP"; then
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FTP" >&5
+#$as_echo "$FTP" >&6; }
+#else
+# { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+#$as_echo "no" >&6; }
+#fi
+#
+#
+# if test x"$FTP" != x"no"; then :
+#
+# FETCHER="$FTP -o"
+#
+#else
+#
+# as_fn_error $? "cannot find wget or ftp" "$LINENO" 5
+#
+#fi
+#
+#fi
++++++ domUloader.py ++++++
#!/usr/bin/env python
# domUloader.py
"""Loader for kernel and (optional) ramdisk from domU filesystem
Given a physical disk (or disk image) for a domU and the path of a kernel and
optional ramdisk, copies the kernel and ramdisk from the domU disk to a
temporary location in dom0.
The --entry parameter specifies the location of the kernel (and optional
ramdisk) within the domU filesystem. dev is the disk as seen by domU.
Filenames are relative to that filesystem.
The disk is passed as the last parameter. It must be a block device or raw
disk image. More complex disk images (QCOW, VMDK, etc) must already be
configured via blktap and presented as a block device.
The script writes an sxpr specifying the locations of the copied kernel and
ramdisk into the file specified by --output (default is stdout).
Limitations:
- It is assumed both kernel and ramdisk are on the same filesystem.
- domUs might use LVM; the script currently does not have support for setting
up LVM mappings for domUs; it's not trivial and we might risk namespace
conflicts. If you want to use LVM inside domUs, set up a small non-LVM boot
partition and specify it in bootentry.
The script uses kpartx (multipath-tools) to create mappings for devices that
are exported as whole disk devices that are partitioned.
(c) 01/2006 Novell Inc
License: GNU GPL
Author: Kurt Garloff
"""
import os, sys, getopt
from stat import *
from xen.xend import sxp
import tempfile
import time
import xnloader
# Global options
quiet = False
verbose = False
dryrun = False
tmpdir = '/var/lib/xen/tmp'
in_args = ''
# kpartx, left to its own devices, does not consistently pick the
# same partition separator. Explicitly specify it.
kpartx_args = '-p -part'
# Helper functions
def kpartx_has_opt(opt):
""" Return True if kpartx supports option opt, otherwise False"""
have_opt = True
kpartx_cmd = 'kpartx -' + opt + ' 2>&1'
p = os.popen(kpartx_cmd)
for line in p.readlines():
if line.find('invalid option') >= 0:
have_opt = False
break
p.close()
return have_opt
def error(s):
print >> sys.stderr, "domUloader error: %s" % s
def verbose_print(s):
if verbose:
print >> sys.stderr, "domUloader: %s" % s
def traildigits(strg):
"""Return the trailing digits, used to split the partition number off"""
idx = len(strg)-1
while strg[idx].isdigit():
if len == 0:
return strg
idx -= 1
return strg[idx+1:]
def getWholedisk(part):
while len(part) and part[len(part)-1].isdigit():
part = part[:-1]
return part
#def isWholedisk(domUname):
# """Determines whether dev is a wholedisk dev"""
# return not domUname[-1:].isdigit()
# If available, add '-f' option (bnc#613584)
if kpartx_has_opt('f'):
kpartx_args += ' -f'
class Wholedisk:
"Class representing a whole disk that may have partitions"
def __init__(self, vdev, pdev):
"c'tor: set up"
# Initialize object; will not raise:
self.ldev = None
self.vdev = vdev
self.pdev = pdev
self.mapped = 0
self.partitions = []
self.pcount = 0
self.lvm = False
# Finish initialization; may raise:
self.is_blk = (S_ISBLK(os.stat(pdev)[ST_MODE]))
self.pcount = self.scanpartitions()
def physdev(self):
"""Gets the physical device used to access the device from dom0"""
if self.ldev:
return self.ldev
return self.pdev
def findPart(self, vdev):
"Find device dev in list of partitions"
if len(vdev) > 5 and vdev[:5] == "/dev/":
vdev = vdev[5:]
for part in self.partitions:
if vdev == part.vdev:
return part
if len(self.partitions):
return self.partitions[0]
return None
def loopsetup(self):
"""Sets up the loop mapping for a disk image.
Will raise if no loopbacks are available.
"""
if not self.is_blk and not self.ldev:
# Loops through all loopback devices, attempting to
# find a free one to set up. Don't scan for free and
# then try to set it up as a separate step - too racy!
i = 0
while True:
ldev = '/dev/loop%i' % (i)
if not os.path.exists(ldev):
break
i += 1
fd = os.popen("losetup %s '%s' 2> /dev/null" % (ldev, self.pdev))
if not fd.close():
verbose_print("losetup %s '%s'" % (ldev, self.pdev))
self.ldev = ldev
break
if not self.ldev:
raise RuntimeError("No free loop device found")
def loopclean(self):
"""Delete the loop mapping.
Will never raise.
"""
if self.ldev:
verbose_print("losetup -d %s" % self.ldev)
# Even seemingly innocent queries like "losetup /dev/loop0"
# can temporarily block the loopback and cause transient
# failures deleting the loopback, hence the retry logic.
retries = 10
while retries:
fd = os.popen("losetup -d %s" % self.ldev)
if not fd.close():
self.ldev = None
break
else:
# Mappings may not have been deleted due to race
# between udev and dm - see bnc#379032. Causes
# loop devices to leak. Call kpartx -d again
os.system("kpartx %s -d '%s'" % (kpartx_args, self.physdev()))
time.sleep(0.1)
retries -= 1
def scanlvmpartitions(self):
pcount = 0
verbose_print("vgchange -ay '%s'" % (self.vdev))
ret = os.system("vgchange -ay '%s' > /dev/null 2>&1" % (self.vdev)) >> 8
if not ret:
self.lvm = True
verbose_print("lvscan | grep '/dev/%s'" % (self.vdev))
fd = os.popen("lvscan | grep '/dev/%s'" % (self.vdev))
for line in fd.readlines():
line = line.strip()
(t1, lvname, t2) = line.split('\'')
pname = lvname[lvname.rfind('/')+1:]
pname = pname.strip()
pname = "/dev/mapper/" + self.vdev + "-" + pname
verbose_print("Found partition: vdev %s, pdev %s" % (self.vdev, pname))
self.partitions.append(Partition(self, self.vdev, pname))
pcount += 1
fd.close()
verbose_print("vgchange -an '%s'" % (self.vdev))
os.system("vgchange -an '%s' > /dev/null 2>&1" % (self.vdev))
else:
verbose_print("vgchange -ay %s ... failed: -%d" % (self.vdev, ret))
return pcount
def scanpartitions(self):
"""Scan device for partitions (kpartx -l) and set up data structures,
Returns number of partitions found."""
self.loopsetup()
# TODO: We could use fdisk -l instead and look at the type of
# partitions; this way we could also detect LVM and support it.
verbose_print("kpartx %s -l '%s'" % (kpartx_args, self.physdev()))
fd = os.popen("kpartx %s -l '%s'" % (kpartx_args, self.physdev()))
pcount = 0
for line in fd.readlines():
line = line.strip()
verbose_print("kpartx -l: %s" % (line,))
(pname, params) = line.split(' : ')
pname = pname.strip()
pno = int(traildigits(pname))
#if pname.rfind('/') != -1:
# pname = pname[pname.rfind('/')+1:]
#pname = self.pdev[:self.pdev.rfind('/')] + '/' + pname
pname = "/dev/mapper/" + pname
verbose_print("Found partition: vdev %s, pdev %s" % ('%s%i' % (self.vdev, pno), pname))
self.partitions.append(Partition(self, '%s%i' % (self.vdev, pno), pname))
pcount += 1
fd.close()
# Try lvm
if not pcount:
pcount = self.scanlvmpartitions()
# Add self to partition table
if not pcount:
if self.ldev:
ref = self
else:
ref = None
self.partitions.append(Partition(ref, self.vdev, self.pdev))
return pcount
def activatepartitions(self):
"Set up loop mapping and device-mapper mappings"
verbose_print("activatepartitions")
if not self.mapped:
self.loopsetup()
if self.pcount:
verbose_print("kpartx %s -a '%s'" % (kpartx_args, self.physdev()))
fd = os.popen("kpartx %s -a '%s'" % (kpartx_args, self.physdev()))
fd.close()
if self.pcount and self.lvm:
verbose_print("vgchange -ay '%s'" % (self.vdev))
ret = os.system("vgchange -ay '%s' > /dev/null 2>&1" % (self.vdev)) >> 8
if not ret:
verbose_print("lvchange -ay '%s'" % (self.vdev))
os.system("lvchange -ay '%s' > /dev/null 2>&1" % (self.vdev))
self.mapped += 1
def partitionsdeactivated(self):
"Return True if partition mappings have been removed, False otherwise"
for part in self.partitions:
if os.access(part.pdev, os.F_OK):
return False
return True
def deactivatepartitions(self):
"""Remove device-mapper mappings and loop mapping.
Will never raise.
"""
verbose_print("deactivatepartitions")
if not self.mapped:
return
self.mapped -= 1
if not self.mapped:
if self.pcount:
retries = 10
while retries and not self.partitionsdeactivated():
verbose_print("kpartx %s -d '%s'" % (kpartx_args, self.physdev()))
os.system("kpartx %s -d '%s'" % (kpartx_args, self.physdev()))
time.sleep(0.1)
retries -= 1
if retries == 0:
error("unable to remove partition mappings with kpartx -d")
if self.pcount and self.lvm:
verbose_print("lvchange -an '%s'" % (self.vdev))
ret = os.system("lvchange -an '%s' > /dev/null 2>&1" % (self.vdev)) >> 8
if ret:
time.sleep(0.3)
os.system("lvchange -an '/dev/%s' > /dev/null 2>&1" % (self.vdev))
verbose_print("vgchange -an '%s'" % (self.vdev))
ret = os.system("vgchange -an '%s' > /dev/null 2>&1" % (self.vdev)) >> 8
if ret:
time.sleep(0.3)
os.system("vgchange -an '%s' > /dev/null 2>&1" % (self.vdev))
self.loopclean()
def __del__(self):
"d'tor: clean up"
self.deactivatepartitions()
self.loopclean()
def __repr__(self):
"string representation for debugging"
strg = "[" + self.vdev + "," + self.pdev + ","
if self.ldev:
strg += self.ldev
strg += "," + str(self.pcount) + ",mapped %ix]" % self.mapped
return strg
class Partition:
"""Class representing a domU filesystem (partition) that can be
mounted in dom0"""
def __init__(self, whole = None, vdev = None, pdev = None):
"c'tor: setup"
self.wholedisk = whole
self.vdev = vdev
self.pdev = pdev
self.mountpoint = None
def __del__(self):
"d'tor: cleanup"
if self.mountpoint:
self.umount()
# Not needed: Refcounting will take care of it.
#if self.wholedisk:
# self.wholedisk.deactivatepartitions()
def __repr__(self):
"string representation for debugging"
strg = "[" + self.vdev + "," + self.pdev + ","
if self.mountpoint:
strg += "mounted on " + self.mountpoint + ","
else:
strg += "not mounted,"
if self.wholedisk:
return strg + self.wholedisk.__repr__() + "]"
else:
return strg + "]"
def mount(self, fstype = None, options = "ro"):
"mount filesystem, sets self.mountpoint"
if self.mountpoint:
return
if self.wholedisk:
self.wholedisk.activatepartitions()
mtpt = tempfile.mkdtemp(prefix = "%s." % self.vdev, dir = tmpdir)
mopts = ""
if fstype:
mopts += " -t %s" % fstype
if options:
mopts += " -o %s" % options
verbose_print("mount %s '%s' %s" % (mopts, self.pdev, mtpt))
fd = os.popen("mount %s '%s' %s" % (mopts, self.pdev, mtpt))
err = fd.close()
if err:
try:
os.rmdir(mtpt)
except:
pass
raise RuntimeError("Error %i from mount %s '%s' on %s" % \
(err, mopts, self.pdev, mtpt))
self.mountpoint = mtpt
def umount(self):
"""umount filesystem at self.mountpoint"""
if not self.mountpoint:
return
verbose_print("umount %s" % self.mountpoint)
fd = os.popen("umount %s" % self.mountpoint)
err = fd.close()
try:
os.rmdir(self.mountpoint)
except:
pass
if err:
error("Error %i from umount %s" % (err, self.mountpoint))
else:
self.mountpoint = None
if self.wholedisk:
self.wholedisk.deactivatepartitions()
def parseEntry(entry):
"disects bootentry and returns vdev, kernel, ramdisk"
def bad():
raise RuntimeError, "Malformed --entry"
fsspl = entry.split(':')
if len(fsspl) != 2:
bad()
vdev = fsspl[0]
entry = fsspl[1]
enspl = entry.split(',')
if len(enspl) not in (1, 2):
bad()
# Prepend '/' if missing
kernel = enspl[0]
if kernel == '':
bad()
if kernel[0] != '/':
kernel = '/' + kernel
ramdisk = None
if len(enspl) > 1:
ramdisk = enspl[1]
if ramdisk != '' and ramdisk[0] != '/':
ramdisk = '/' + ramdisk
return vdev, kernel, ramdisk
def copyFile(src, dst):
"Wrapper for shutil.filecopy"
import shutil
verbose_print("cp %s %s" % (src, dst))
stat = os.stat(src)
if stat.st_size > 32*1024*1024:
raise RuntimeError("Too large file %s (%s larger than 32MB)" \
% (src, stat.st_size))
try:
shutil.copyfile(src, dst)
except:
os.unlink(dst)
raise()
def copyKernelAndRamdisk(disk, vdev, kernel, ramdisk):
"""Finds vdev in list of partitions, mounts the partition, copies
kernel [and ramdisk] off to dom0 files, umounts the parition again,
and returns sxpr pointing to these copies."""
verbose_print("copyKernelAndRamdisk(%s, %s, %s, %s)" % (disk, vdev, kernel, ramdisk))
if dryrun:
return "linux (kernel kernel.dummy) (ramdisk ramdisk.dummy)"
part = disk.findPart(vdev)
if not part:
raise RuntimeError("Partition '%s' does not exist" % vdev)
part.mount()
try:
(fd, knm) = tempfile.mkstemp(prefix = "kernel.", dir = tmpdir)
os.close(fd)
copyFile(part.mountpoint + kernel, knm)
except:
os.unlink(knm)
part.umount()
raise
if not quiet:
print "Copy kernel %s from %s to %s for booting" % (kernel, vdev, knm)
sxpr = "linux (kernel %s)" % knm
if ramdisk:
try:
(fd, inm) = tempfile.mkstemp(prefix = "ramdisk.", dir = tmpdir)
os.close(fd)
copyFile(part.mountpoint + ramdisk, inm)
except:
os.unlink(knm)
os.unlink(inm)
part.umount()
raise
sxpr += "(ramdisk %s)" % inm
part.umount()
xnloader.patch_netware_loader(knm)
return sxpr
def main(argv):
"Main routine: Parses options etc."
global quiet, dryrun, verbose, tmpdir, in_args
def usage():
"Help output (usage info)"
global verbose, quiet, dryrun
print >> sys.stderr, "domUloader usage: domUloader [--output=fd] [--quiet] [--dryrun] [--verbose]\n" +\
"[--args] [--help] --entry=dev:kernel[,ramdisk] physdisk [virtdisk]\n" +\
"\n" +\
"dev format: hd[a-p][0-9]*, xvd[a-p][0-9]*, LVM-vgname-lvname\n"
print >> sys.stderr, __doc__
try:
(optlist, args) = getopt.gnu_getopt(argv, 'qvh', \
('entry=', 'output=', 'tmpdir=', 'args=', 'kernel=', 'ramdisk=', 'help', 'quiet', 'dryrun', 'verbose'))
except:
usage()
sys.exit(1)
entry = None
output = None
pdisk = None
vdisk = None
for (opt, oarg) in optlist:
if opt in ('-h', '--help'):
usage()
sys.exit(1)
elif opt in ('-q', '--quiet'):
quiet = True
elif opt in ('-n', '--dryrun'):
dryrun = True
elif opt in ('-v', '--verbose'):
verbose = True
elif opt == '--output':
output = oarg
elif opt == '--entry':
entry = oarg
elif opt == '--tmpdir':
tmpdir = oarg
elif opt == '--args':
in_args = oarg
verbose_print(str(argv))
if args:
if len(args) == 2:
pdisk = args[1]
elif len(args) == 3:
pdisk = args[1]
vdisk = args[2]
if not entry or not pdisk:
usage()
sys.exit(1)
if output is None or output == "-":
fd = sys.stdout.fileno()
else:
fd = os.open(output, os.O_WRONLY)
if not os.access(tmpdir, os.X_OK):
os.mkdir(tmpdir)
os.chmod(tmpdir, 0750)
vdev, kernel, ramdisk = parseEntry(entry)
if vdev[:vdev.find('-')] == "LVM":
vdev = vdev.split('-')[1]
if not vdisk:
vdisk = getWholedisk(vdev)
verbose_print("vdisk not specified; guessing '%s' based on '%s'" % (vdisk, vdev))
if not vdev.startswith(vdisk):
error("Virtual disk '%s' does not match entry '%s'" % (vdisk, entry))
sys.exit(1)
disk = Wholedisk(vdisk, pdisk)
r = 0
try:
sxpr = copyKernelAndRamdisk(disk, vdev, kernel, ramdisk)
if in_args:
sxpr += "(args '%s')" % in_args
os.write(fd, sxpr)
except Exception, e:
error(str(e))
r = 1
for part in disk.partitions:
part.wholedisk = None
del disk
return r
# Call main if called (and not imported)
if __name__ == "__main__":
r = 1
try:
r = main(sys.argv)
except Exception, e:
error(str(e))
sys.exit(r)
++++++ etc_pam.d_xen-api ++++++
#%PAM-1.0
auth required pam_listfile.so onerr=fail item=user \
sense=allow file=/etc/xen/xenapiusers
auth include common-auth
account include common-account
password include common-password
session include common-session
++++++ hibernate.patch ++++++
Index: xen-4.2.0-testing/tools/firmware/hvmloader/acpi/ssdt_s3.asl
===================================================================
--- xen-4.2.0-testing.orig/tools/firmware/hvmloader/acpi/ssdt_s3.asl
+++ xen-4.2.0-testing/tools/firmware/hvmloader/acpi/ssdt_s3.asl
@@ -20,13 +20,9 @@
DefinitionBlock ("SSDT_S3.aml", "SSDT", 2, "Xen", "HVM", 0)
{
- /* Must match piix emulation */
- Name (\_S3, Package (0x04)
- {
- 0x01, /* PM1a_CNT.SLP_TYP */
- 0x01, /* PM1b_CNT.SLP_TYP */
- 0x0, /* reserved */
- 0x0 /* reserved */
- })
+ /*
+ * Turn off support for s3 sleep state to deal with SVVP tests.
+ * This is what MSFT does on HyperV.
+ */
}
Index: xen-4.2.0-testing/tools/firmware/hvmloader/acpi/ssdt_s4.asl
===================================================================
--- xen-4.2.0-testing.orig/tools/firmware/hvmloader/acpi/ssdt_s4.asl
+++ xen-4.2.0-testing/tools/firmware/hvmloader/acpi/ssdt_s4.asl
@@ -20,13 +20,9 @@
DefinitionBlock ("SSDT_S4.aml", "SSDT", 2, "Xen", "HVM", 0)
{
- /* Must match piix emulation */
- Name (\_S4, Package (0x04)
- {
- 0x00, /* PM1a_CNT.SLP_TYP */
- 0x00, /* PM1b_CNT.SLP_TYP */
- 0x00, /* reserved */
- 0x00 /* reserved */
- })
+ /*
+ * Turn off support for s4 sleep state to deal with SVVP tests.
+ * This is what MSFT does on HyperV.
+ */
}
++++++ hotplug-Linux-block-find-free-loop-fix.patch ++++++
--- xen-4.2.5-testing/tools/hotplug/Linux/block.orig 2015-02-18 14:59:01.000000000 -0700
+++ xen-4.2.5-testing/tools/hotplug/Linux/block 2015-02-18 15:00:07.000000000 -0700
@@ -21,7 +21,7 @@ find_free_loopback_helper() {
local busy_devnum
while read busy_devnum; do
if [ "$next_devnum" != "$busy_devnum" ]; then
- break
+ case "$busy_devnum" in *[0-9]*) break;; esac
fi
let next_devnum=$next_devnum+1
done
++++++ init.pciback ++++++
#!/bin/bash
#
# Copyright (c) 2014 SUSE GmbH Nuernberg, Germany. All rights reserved.
#
# /etc/init.d/pciback
#
### BEGIN INIT INFO
# Provides: pciback
# Required-Start: $syslog $network
# Should-Start: $null
# Required-Stop: $syslog $network
# Should-Stop: $null
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: bind PCI devices to pciback
### END INIT INFO
. /etc/rc.status
. /etc/sysconfig/pciback
rc_reset
load_pciback() {
if ! lsmod | grep -qi "pciback"
then
echo "Loading pciback ..."
modprobe pciback
fi
}
unload_pciback() {
if lsmod | grep -qi "pciback"
then
echo "Unloading pciback ..."
modprobe -r pciback
fi
}
bind_dev_to_pciback() {
for DEVICE in ${XEN_PCI_HIDE_LIST}
do
local DRV=`echo ${DEVICE} | /usr/bin/cut -d "," -f 1`
local PCIID=`echo ${DEVICE} | /usr/bin/cut -d "," -f 2`
if ! ls /sys/bus/pci/drivers/pciback/${PCIID} > /dev/null 2>&1
then
echo "Binding ${PCIID} ..."
if ls /sys/bus/pci/drivers/${DRV}/${PCIID} > /dev/null 2>&1
then
echo -n ${PCIID} > /sys/bus/pci/drivers/${DRV}/unbind
fi
echo -n ${PCIID} > /sys/bus/pci/drivers/pciback/new_slot
echo -n ${PCIID} > /sys/bus/pci/drivers/pciback/bind
fi
done
}
unbind_dev_from_pciback() {
for DEVICE in ${XEN_PCI_HIDE_LIST}
do
local DRV=`echo ${DEVICE} | /usr/bin/cut -d "," -f 1`
local PCIID=`echo ${DEVICE} | /usr/bin/cut -d "," -f 2`
if ls /sys/bus/pci/drivers/pciback/${PCIID} > /dev/null
then
echo "Unbinding ${PCIID} ..."
echo -n ${PCIID} > /sys/bus/pci/drivers/pciback/unbind
fi
done
}
test "uname -r" | grep xen && exit 0
case $1 in
start)
echo "Starting pciback ..."
echo
load_pciback
bind_dev_to_pciback
rc_status -v -r
;;
stop)
echo "Stopping pciback ..."
echo
unbind_dev_from_pciback
unload_pciback
rc_status -v
;;
reload|restart)
echo "Stopping pciback ..."
echo
unbind_dev_from_pciback
unload_pciback
echo "Starting pciback ..."
echo
load_pciback
bind_dev_to_pciback
;;
status)
if lsmod | grep -qi pciback
then
echo
echo "pciback: loaded"
echo
echo "Currently bound devices ..."
echo "-----------------------------"
ls /sys/bus/pci/drivers/pciback | grep ^0000
echo
else
echo "pciback: not loaded"
fi
;;
*)
echo "Usage: $0 [start|stop|restart|reload|status]"
exit 1
;;
esac
++++++ init.xen_loop ++++++
# Increase the number of loopback devices available for vm creation
options loop max_loop=64
++++++ init.xend ++++++
#!/bin/bash
#
# xend Starts and stops the Xen management daemon
#
# chkconfig: 35 98 01
# description: Starts and stops the Xen management daemon
#
### BEGIN INIT INFO
# Provides: xend
# Required-Start: $syslog $network $remote_fs
# Should-Start: iscsi $time
# Required-Stop: $syslog $network $remote_fs
# Should-Stop: iscsi $time
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: Starts and stops the Xen management daemon
# Description: Starts and stops the Xen management daemon. xend is needed
# to create and manage VMs on Xen.
### END INIT INFO
. /etc/rc.status
rc_reset
XEND=`pidof -x /usr/sbin/xend`
await_daemons_up()
{
i=1
rets=10
xend status
while [ $? -ne 0 -a $i -lt $rets ]; do
sleep 1
echo -n .
i=$(($i + 1))
xend status
done
}
xend_abort()
{
echo -n "xend "
rc_failed $1
rc_status -v
rc_exit
}
cleanup()
{
rm -f /var/lib/xen/tmp/* 2>/dev/null
rm -f /var/lib/xen/xenbl* 2>/dev/null
}
check()
{
if [ "$1" == status ]; then
if [ ! -e /proc/xen/capabilities ]; then
xend_abort 3
fi
else
if [ `id -u` != 0 ]; then
xend_abort 4
fi
if [ ! -e /proc/xen/capabilities ] ||
! grep control_d /proc/xen/capabilities >/dev/null 2>&1; then
if [ "$1" == stop ] ||
[ "$1" == try-restart ]; then
xend_abort 0
else
xend_abort 6
fi
fi
fi
}
case "$1" in
start)
check $1
echo -n "Starting xend "
if [ ! -z "$XEND" ]; then
echo -n "(already running pid $XEND) "
else
cleanup
fi
xend start
await_daemons_up
;;
stop)
check $1
echo -n "Stopping xend "
if [ -z "$XEND" ]; then
echo -n "(not running) "
xend stop
rc_reset
else
echo -n "(pid $XEND) "
xend stop
cleanup
rc_reset
fi
;;
status)
check $1
echo -n "Checking status of xend "
if [ ! -z "$XEND" ]; then
echo -n "(pid $XEND) "
fi
checkproc /usr/sbin/xend
;;
restart|reload)
check $1
echo -n "Restarting xend "
if [ -z "$XEND" ]; then
echo -n "(not running) "
else
echo -n "(old pid $XEND) "
fi
xend restart
await_daemons_up
;;
try-restart)
check $1
$0 status
if [ $? = 0 ]; then
$0 restart
else
rc_reset
fi
;;
*)
echo "Usage: $0 {start|stop|restart|try-restart|reload|status}"
rc_failed 2
rc_exit
esac
rc_status -v
rc_exit
++++++ init.xendomains ++++++
#!/bin/bash
#
# xendomains Starts and stops Xen VMs
#
# chkconfig: 35 99 00
# description: Starts and stops Xen VMs
#
### BEGIN INIT INFO
# Provides: xendomains
# Required-Start: $syslog $remote_fs xenstored xenconsoled
# Should-Start: xend iscsi o2cb ocfs2
# Required-Stop: $syslog $remote_fs xenstored xenconsoled
# Should-Stop: xend iscsi
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: Starts and stops Xen VMs
# Description: Starts and stops Xen VMs automatically when the
# host starts and stops.
### END INIT INFO
. /etc/rc.status
rc_reset
RETCODE_FILE=/tmp/xendomains.rc.$$
xm_cmd=echo
# See docs/misc/distro_mapping.txt
if [ -d /var/lock/subsys ]; then
LOCKFILE=/var/lock/subsys/xendomains
else
LOCKFILE=/var/lock/xendomains
fi
if [ -d /etc/sysconfig ]; then
XENDOM_CONFIG=/etc/sysconfig/xendomains
else
XENDOM_CONFIG=/etc/default/xendomains
fi
test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
if [ "$1" = "stop" ]; then exit 0;
else exit 6; fi; }
. "$XENDOM_CONFIG"
shopt -s dotglob nullglob
smart_term=1
if [ -z "$esc" ]; then
smart_term=0
rc_timer_on()
{
(trap "exit 0" TERM; sleep $1) & _rc_timer_pid=$!
}
rc_timer_off()
{
if [ -n "$_rc_timer_pid" ]; then
kill -TERM $_rc_timer_pid > /dev/null 2>&1
fi
unset _rc_timer_pid
}
fi
xendomains_abort()
{
echo -n "xendomains "
rc_failed $1
rc_status -v
rc_exit
}
check()
{
XEND=`pidof -x /usr/sbin/xend`
if [ -z "$XEND" ]; then
xm_cmd="xl -f"
XEND="xl"
else
xm_cmd="xm"
fi
if [ "$1" = status ]; then
if [ ! -e /proc/xen/capabilities ] || [ ! -r "$XENDOM_CONFIG" ] || [ -z "$XEND" ]; then
xendomains_abort 3
fi
else
if [ `id -u` != 0 ]; then
xendomains_abort 4
fi
if [ ! -e /proc/xen/capabilities ] || [ -z "$XEND" ] ||
! grep control_d /proc/xen/capabilities >/dev/null 2>&1; then
if [ "$1" = stop ] ||
[ "$1" = restart ]; then
xendomains_abort 0
else
xendomains_abort 6
fi
fi
if [ ! -r "$XENDOM_CONFIG" ]; then
xendomains_abort 6
fi
fi
}
dir_contains_something()
{
[ -d "$1" ] || return 1
local dirfiles=( "$1"/* )
[ ${#dirfiles[@]} != 0 ]
}
get_name_from_cfg()
{
if grep -q "^name" "$1";then
NM=`grep '^name[ ]*=' "$1" | sed -e 's/^name[ ]*=[ ]*['\''"]\([^'\''"]*\)['\''"].*$/\1/'`
elif grep -q "(name " "$1";then
NM=`grep '(name ' "$1" | sed -e 's/^ *//' | cut -d " " -f 2 | sed -e 's/)//'`
fi
}
running_auto_names()
{
unset AUTONAMES[@]
if ! dir_contains_something "$XENDOMAINS_AUTO"; then
return
fi
for dom in "$XENDOMAINS_AUTO"/*; do
get_name_from_cfg "$dom"
AUTONAMES+=("$NM")
done
}
parseln()
{
name=${1:0:$((${#1}-36))}
name=${name%% *}
rest="${1: -36}"
id=${rest:0:4}
id=`echo $id`
mem=${rest:4:6}
mem=`echo $mem`
vcpu=${rest:10:6}
vcpu=`echo $vcpu`
state=${rest:16:11}
state=`echo $state`
tm=${rest:27}
tm=`echo $tm`
}
xm_list()
{
TERM=vt100 ${xm_cmd} list | grep -v '^Name *ID'
}
is_cfg_running()
{
get_name_from_cfg "$1"
while read LN; do
parseln "$LN"
[ "$id" = 0 ] && continue
if [ "$name" = "$NM" ]; then
[ -z "$state" ] && return 1
return 0
fi
done < <(xm_list)
return 1
}
start()
{
if [ -f "$LOCKFILE" ]; then
echo -n "xendomains already running (lockfile exists)"
rc_reset
rc_status -v
return 0
fi
local printed=0
if [ "$XENDOMAINS_RESTORE" = "true" ] &&
dir_contains_something "$XENDOMAINS_SAVE"; then
mkdir -p $(dirname "$LOCKFILE")
touch "$LOCKFILE"
echo "Restoring saved Xen domains"
printed=1
for dom in "$XENDOMAINS_SAVE"/*; do
echo -n " ${dom##*/}: "
${xm_cmd} restore "$dom" >/dev/null 2>&1
if [ $? -ne 0 ]; then
rc_failed
else
rc_reset
rm -f "$dom"
fi
rc_status -v
done
fi
if dir_contains_something "$XENDOMAINS_AUTO"; then
touch "$LOCKFILE"
echo "Starting auto Xen domains"
printed=1
for dom in "$XENDOMAINS_AUTO"/*; do
echo -n " ${dom##*/}: "
if is_cfg_running "$dom"; then
rc_status -s
else
if grep -q "^name" "$dom";then
${xm_cmd} create --quiet --defconfig "$dom"
elif grep -q "(name .*" "$dom";then
${xm_cmd} create --quiet --config "$dom"
fi
if [ $? -ne 0 ]; then
rc_failed
else
usleep $XENDOMAINS_CREATE_USLEEP
rc_reset
fi
rc_status -v
fi
done
fi
if [ $printed -eq 0 ]; then
echo -n "Starting xendomains"
rc_failed 6 # not configured
rc_status -v
fi
}
is_zombie_state()
{
[ "$1" = "-b---d" ] || [ "$1" = "-----d" ]
}
any_non_zombies()
{
while read LN; do
parseln "$LN"
[ "$id" = 0 ] && continue
[ -z "$state" ] && continue
is_zombie_state "$state" || return 0
done < <(xm_list)
return 1
}
migrate_with_watchdog()
{
(${xm_cmd} migrate "$@" ; echo $? > "$RETCODE_FILE") >/dev/null 2>&1 &
watchdog_xm $!
}
save_with_watchdog()
{
(${xm_cmd} save "$@" ; echo $? > "$RETCODE_FILE") >/dev/null 2>&1 &
watchdog_xm $!
}
shutdown_with_watchdog()
{
(${xm_cmd} shutdown -w "$@" ; echo $? > "$RETCODE_FILE") >/dev/null 2>&1 &
watchdog_xm $!
}
get_return_code()
{
local RC=127
[ -r "$RETCODE_FILE" ] && RC=`head -c10 "$RETCODE_FILE"`
rm -f "$RETCODE_FILE"
return $RC
}
# $1: The PID to wait on.
watchdog_xm()
{
local col=$((COLUMNS-11))
if [ -z "$XENDOMAINS_STOP_MAXWAIT" ] || [ "$XENDOMAINS_STOP_MAXWAIT" = "0" ]; then
wait $1 >/dev/null 2>&1
get_return_code
return
fi
rc_timer_on $XENDOMAINS_STOP_MAXWAIT $col
while true; do
# Prefer "jobs" over "ps": faster and no false positives
pid=`jobs -l | grep " $1 Running"`
if [ -z "$pid" ]; then
break
fi
pid=`jobs -l | grep " $_rc_timer_pid Running"`
if [ -z "$pid" ]; then
disown $1 # To avoid the "Terminated..." message
kill $1 >/dev/null 2>&1
fi
sleep 1
done
rc_timer_off
if [ $smart_term -ne 0 ]; then
echo -en "\015${esc}[${col}C "
fi
get_return_code
}
stop()
{
echo "Shutting down Xen domains"
if [ "$XENDOMAINS_AUTO_ONLY" = "true" ]; then
running_auto_names
fi
local printed=0
while read LN; do
parseln "$LN"
[ "$id" = 0 ] && continue
[ -z "$state" ] && continue
printed=1
if [ "$XENDOMAINS_AUTO_ONLY" = "true" ]; then
is_auto_domain=0
for n in "${AUTONAMES[@]}"; do
if [ "$name" = "$n" ]; then
is_auto_domain=1
break
fi
done
if [ $is_auto_domain -eq 0 ]; then
echo -n " $name: "
rc_status -s
continue
fi
fi
if [ -n "$XENDOMAINS_SYSRQ" ]; then
for sysrq in $XENDOMAINS_SYSRQ; do
echo -n " $name: "
echo -n "sending sysrq '$sysrq'... "
${xm_cmd} sysrq $id $sysrq
if [ $? -ne 0 ]; then
rc_failed
else
rc_reset
fi
rc_status -v
# usleep just ignores empty arg
usleep $XENDOMAINS_USLEEP
done
fi
if is_zombie_state "$state"; then
echo -n " $name: "
echo -n "destroying zombie... "
${xm_cmd} destroy $id
rc_reset
rc_status -v
continue
fi
if [ -n "$XENDOMAINS_MIGRATE" ]; then
echo -n " $name: "
echo -n "migrating... "
migrate_with_watchdog $id "$XENDOMAINS_MIGRATE"
if [ $? -ne 0 ]; then
rc_failed
rc_status -v
else
rc_reset
rc_status -v
continue
fi
fi
if [ -n "$XENDOMAINS_SAVE" ]; then
echo -n " $name: "
echo -n "saving... "
save_with_watchdog $id "$XENDOMAINS_SAVE/$name"
if [ $? -ne 0 ]; then
rm -f "$XENDOMAINS_SAVE/$name"
rc_failed
rc_status -v
else
rc_reset
rc_status -v
continue
fi
fi
if [ -n "$XENDOMAINS_SHUTDOWN" ]; then
echo -n " $name: "
echo -n "shutting down... "
shutdown_with_watchdog $id $XENDOMAINS_SHUTDOWN
if [ $? -ne 0 ]; then
rc_failed
else
rc_reset
fi
rc_status -v
fi
done < <(xm_list)
if [ -n "$XENDOMAINS_SHUTDOWN_ALL" ] && any_non_zombies ; then
echo -n " others: shutting down... "
shutdown_with_watchdog $XENDOMAINS_SHUTDOWN_ALL
if [ $? -ne 0 ]; then
rc_failed
else
rc_reset
fi
rc_status -v
fi
if [ $printed -eq 0 ]; then
echo -e "${rc_done_up}"
fi
# Unconditionally delete lock file
rm -f "$LOCKFILE"
}
check_domain_up()
{
while read LN; do
parseln "$LN"
[ "$id" = 0 ] && continue
if [ "$name" = "$1" ]; then
[ -z "$state" ] && return 1
return 0
fi
done < <(xm_list)
return 1
}
check_all_domains_up()
{
any_auto=0
any_save=0
dir_contains_something "$XENDOMAINS_AUTO" && any_auto=1
dir_contains_something "$XENDOMAINS_SAVE" && any_save=1
if [ $any_auto -eq 0 ] && [ $any_save -eq 0 ]; then
rc_reset
rc_status -v
return
fi
echo
if [ $any_auto -ne 0 ]; then
for nm in "$XENDOMAINS_AUTO"/*; do
get_name_from_cfg "$nm"
echo -n " $nm: "
if check_domain_up "$NM"; then
rc_reset
else
rc_failed 2
fi
rc_status -v
done
fi
if [ $any_save -ne 0 ]; then
for nm in "$XENDOMAINS_SAVE"/*; do
echo -n " $nm: "
rc_failed 3
rc_status -v
done
fi
}
# This does NOT necessarily restart all running domains: instead it
# stops all running domains and then boots all the domains specified in
# AUTODIR. If other domains have been started manually then they will
# not get restarted.
restart()
{
"$0" stop
start
}
case "$1" in
start)
check $1
start
;;
stop)
check $1
stop
;;
restart|reload)
check $1
restart
;;
try-restart)
check $1
"$0" status
if [ $? = 0 ]; then
"$0" restart
else
rc_reset
rc_status -v
fi
;;
status)
check $1
echo -n "Checking status of Xen domains"
if [ ! -f "$LOCKFILE" ]; then
rc_failed 3
rc_status -v
else
check_all_domains_up
fi
;;
*)
echo "Usage: $0 {start|stop|restart|try-restart|reload|status}"
rc_failed 2
;;
esac
rc_exit
++++++ ioemu-7615-qcow2-fix-alloc_cluster_link_l2.patch ++++++
qcow2 corruption: Fix alloc_cluster_link_l2 (Kevin Wolf)
This patch fixes a qcow2 corruption bug introduced in SVN Rev 5861. L2 tables
are big endian, so entries must be converted before being passed to functions.
This bug is easy to trigger. The following script will create and destroy a
qcow2 image (the header is gone after three loop iterations):
#!/bin/bash
qemu-img create -f qcow2 test.qcow 1M
for i in $(seq 1 10); do
qemu-system-x86_64 -hda test.qcow -monitor stdio > /dev/null 2>&1 <
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block-qcow2.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block-qcow2.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block-qcow2.c
@@ -916,7 +916,7 @@ static int alloc_cluster_link_l2(BlockDr
goto err;
for (i = 0; i < j; i++)
- free_any_clusters(bs, old_cluster[i], 1);
+ free_any_clusters(bs, be64_to_cpu(old_cluster[i]) & ~QCOW_OFLAG_COPIED, 1);
ret = 0;
err:
++++++ ioemu-bdrv-open-CACHE_WB.patch ++++++
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
@@ -247,8 +247,11 @@ static int open_disk(struct td_state *s,
drv = blktap_drivers[i].drv;
DPRINTF("%s driver specified\n", drv ? drv->format_name : "No");
- /* Open the image */
- if (bdrv_open2(bs, path, flags, drv) != 0) {
+ /* Open the image
+ * Use BDRV_O_CACHE_WB for write-through caching,
+ * no flags for write-back caching
+ */
+ if (bdrv_open2(bs, path, flags|BDRV_O_CACHE_WB, drv) != 0) {
fprintf(stderr, "Could not open image file %s\n", path);
return -ENOMEM;
}
++++++ ioemu-blktap-barriers.patch ++++++
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
@@ -360,6 +360,15 @@ static void qemu_send_responses(void* op
}
/**
+ * Callback function for AIO flush
+ */
+static void qemu_flush_response(void* opaque, int ret) {
+ if (ret != 0) {
+ DPRINTF("aio_flush: ret = %d (%s)\n", ret, strerror(-ret));
+ }
+}
+
+/**
* Callback function for the IO message pipe. Reads requests from the ring
* and processes them (call qemu read/write functions).
*
@@ -378,6 +387,7 @@ static void handle_blktap_iomsg(void* pr
blkif_t *blkif = s->blkif;
tapdev_info_t *info = s->ring_info;
int page_size = getpagesize();
+ int sync;
struct aiocb_info *aiocb_info;
@@ -410,7 +420,7 @@ static void handle_blktap_iomsg(void* pr
/* Don't allow writes on readonly devices */
if ((s->flags & TD_RDONLY) &&
- (req->operation == BLKIF_OP_WRITE)) {
+ (req->operation != BLKIF_OP_READ)) {
blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
goto send_response;
}
@@ -431,7 +441,7 @@ static void handle_blktap_iomsg(void* pr
DPRINTF("Sector request failed:\n");
DPRINTF("%s request, idx [%d,%d] size [%llu], "
"sector [%llu,%llu]\n",
- (req->operation == BLKIF_OP_WRITE ?
+ (req->operation != BLKIF_OP_READ ?
"WRITE" : "READ"),
idx,i,
(long long unsigned)
@@ -444,8 +454,14 @@ static void handle_blktap_iomsg(void* pr
blkif->pending_list[idx].secs_pending += nsects;
- switch (req->operation)
+ sync = 0;
+ switch (req->operation)
{
+ case BLKIF_OP_WRITE_BARRIER:
+ sync = 1;
+ bdrv_aio_flush(s->bs, qemu_flush_response, NULL);
+ /* fall through */
+
case BLKIF_OP_WRITE:
aiocb_info = malloc(sizeof(*aiocb_info));
@@ -465,6 +481,10 @@ static void handle_blktap_iomsg(void* pr
DPRINTF("ERROR: bdrv_write() == NULL\n");
goto send_response;
}
+
+ if (sync)
+ bdrv_aio_flush(s->bs, qemu_flush_response, NULL);
+
break;
case BLKIF_OP_READ:
++++++ ioemu-blktap-fv-init.patch ++++++
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_machine_fv.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_machine_fv.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_machine_fv.c
@@ -270,6 +270,7 @@ void qemu_invalidate_entry(uint8_t *buff
#endif /* defined(MAPCACHE) */
+extern void init_blktap(void);
static void xen_init_fv(ram_addr_t ram_size, int vga_ram_size,
const char *boot_device,
@@ -295,6 +296,11 @@ static void xen_init_fv(ram_addr_t ram_s
}
#endif
+#ifndef CONFIG_STUBDOM
+ /* Initialize tapdisk client */
+ init_blktap();
+#endif
+
#ifdef CONFIG_STUBDOM /* the hvmop is not supported on older hypervisors */
xc_set_hvm_param(xc_handle, domid, HVM_PARAM_DM_DOMAIN, DOMID_SELF);
#endif
++++++ ioemu-blktap-image-format.patch ++++++
From 5ac882a6d7499e4a36103db071203bf4d1ddfe1f Mon Sep 17 00:00:00 2001
From: Kevin Wolf
Date: Tue, 10 Mar 2009 16:26:45 +0100
Subject: [PATCH 2/6] ioemu: Use the image format sent by blktapctrl
Currently the blktap backend in ioemu lets qemu guess which format an
image is in. This was a security problem and the blktap backend
doesn't work any more since this was fixed in qemu.
This patch changes ioemu to respect the format it gets from blktapctrl.
Signed-off-by: Kevin Wolf
---
hw/xen_blktap.c | 22 +++++++++++++++++++---
hw/xen_blktap.h | 14 ++++++++++++++
2 files changed, 33 insertions(+), 3 deletions(-)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
@@ -218,9 +218,10 @@ static int map_new_dev(struct td_state *
return -1;
}
-static int open_disk(struct td_state *s, char *path, int readonly)
+static int open_disk(struct td_state *s, char *path, int driver, int readonly)
{
BlockDriverState* bs;
+ BlockDriver* drv;
char* devname;
static int devnumber = 0;
int i;
@@ -230,7 +231,22 @@ static int open_disk(struct td_state *s,
bs = bdrv_new(devname);
free(devname);
- if (bdrv_open(bs, path, 0) != 0) {
+ /* Search for disk driver */
+ for (i = 0; blktap_drivers[i].idnum >= 0; i++) {
+ if (blktap_drivers[i].idnum == driver)
+ break;
+ }
+
+ if (blktap_drivers[i].idnum < 0) {
+ fprintf(stderr, "Could not find image format id %d\n", driver);
+ return -ENOMEM;
+ }
+
+ drv = blktap_drivers[i].drv;
+ DPRINTF("%s driver specified\n", drv ? drv->format_name : "No");
+
+ /* Open the image */
+ if (bdrv_open2(bs, path, 0, drv) != 0) {
fprintf(stderr, "Could not open image file %s\n", path);
return -ENOMEM;
}
@@ -521,7 +537,7 @@ static void handle_blktap_ctrlmsg(void*
s = state_init();
/*Open file*/
- if (s == NULL || open_disk(s, path, msg->readonly)) {
+ if (s == NULL || open_disk(s, path, msg->drivertype, msg->readonly)) {
msglen = sizeof(msg_hdr_t);
msg->type = CTLMSG_IMG_FAIL;
msg->len = msglen;
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.h
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.h
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.h
@@ -52,4 +52,18 @@ typedef struct fd_list_entry {
int init_blktap(void);
+typedef struct disk_info {
+ int idnum;
+ struct BlockDriver *drv;
+} disk_info_t;
+
+static disk_info_t blktap_drivers[] = {
+ { DISK_TYPE_AIO, &bdrv_raw },
+ { DISK_TYPE_SYNC, &bdrv_raw },
+ { DISK_TYPE_VMDK, &bdrv_vmdk },
+ { DISK_TYPE_QCOW, &bdrv_qcow },
+ { DISK_TYPE_QCOW2, &bdrv_qcow2 },
+ { -1, NULL }
+};
+
#endif /*XEN_BLKTAP_H_*/
++++++ ioemu-blktap-zero-size.patch ++++++
From cb982fd919a52ff86f01025d0f92225bc7b2a956 Mon Sep 17 00:00:00 2001
From: Kevin Wolf
Date: Tue, 10 Mar 2009 16:44:31 +0100
Subject: [PATCH 5/6] ioemu: Fail on too small blktap disks
The blktap infrastructure doesn't seems to be able to cope with images
that are smaller than a sector, it produced hangs for me. Such an
image isn't really useful anyway, so just fail gracefully.
Signed-off-by: Kevin Wolf
---
hw/xen_blktap.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
@@ -256,6 +256,12 @@ static int open_disk(struct td_state *s,
s->size = bs->total_sectors;
s->sector_size = 512;
+ if (s->size == 0) {
+ fprintf(stderr, "Error: Disk image %s is too small\n",
+ path);
+ return -ENOMEM;
+ }
+
s->info = ((s->flags & TD_RDONLY) ? VDISK_READONLY : 0);
#ifndef QEMU_TOOL
Index: xen-4.2.0-testing/tools/python/xen/xend/server/DevController.py
===================================================================
--- xen-4.2.0-testing.orig/tools/python/xen/xend/server/DevController.py
+++ xen-4.2.0-testing/tools/python/xen/xend/server/DevController.py
@@ -155,7 +155,7 @@ class DevController:
(devid, self.deviceClass))
elif status == Error:
- self.destroyDevice(devid, False)
+ self.destroyDevice(devid, True)
if err is None:
raise VmError("Device %s (%s) could not be connected. "
"Backend device not found." %
++++++ ioemu-disable-emulated-ide-if-pv.patch ++++++
Index: xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
===================================================================
--- xen-4.2.3-testing.orig/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
+++ xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
@@ -1,6 +1,8 @@
#ifndef QEMU_XEN_H
#define QEMU_XEN_H
+#include "hw/boards.h"
+
/* vl.c */
extern int restore;
extern int vga_ram_size;
@@ -65,7 +67,7 @@ void handle_buffered_pio(void);
/* xenstore.c */
void xenstore_init(void);
uint32_t xenstore_read_target(void);
-void xenstore_parse_domain_config(int domid);
+void xenstore_parse_domain_config(int domid, QEMUMachine *machine);
int xenstore_parse_disable_pf_config(void);
int xenstore_fd(void);
void xenstore_process_event(void *opaque);
Index: xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/vl.c
===================================================================
--- xen-4.2.3-testing.orig/tools/qemu-xen-traditional-dir-remote/vl.c
+++ xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/vl.c
@@ -5862,9 +5862,9 @@ int main(int argc, char **argv, char **e
if ((msg = xenbus_read(XBT_NIL, "domid", &domid_s)))
fprintf(stderr,"Can not read our own domid: %s\n", msg);
else
- xenstore_parse_domain_config(atoi(domid_s));
+ xenstore_parse_domain_config(atoi(domid_s), machine);
#else
- xenstore_parse_domain_config(domid);
+ xenstore_parse_domain_config(domid, machine);
#endif /* CONFIG_STUBDOM */
}
Index: xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.2.3-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -446,7 +446,7 @@ void xenstore_init(void)
}
}
-void xenstore_parse_domain_config(int hvm_domid)
+void xenstore_parse_domain_config(int hvm_domid, QEMUMachine *machine)
{
char **e_danger = NULL;
char *buf = NULL;
@@ -740,11 +740,19 @@ void xenstore_parse_domain_config(int hv
#endif
- drives_table[nb_drives].bdrv = bs;
- drives_table[nb_drives].used = 1;
- media_filename[nb_drives] = strdup(bs->filename);
- nb_drives++;
-
+ if (machine == &xenfv_machine) {
+ drives_table[nb_drives].bdrv = bs;
+ drives_table[nb_drives].used = 1;
+#ifdef CONFIG_STUBDOM
+ media_filename[nb_drives] = strdup(danger_buf);
+#else
+ media_filename[nb_drives] = strdup(bs->filename);
+#endif
+ nb_drives++;
+ } else {
+ qemu_aio_flush();
+ bdrv_close(bs);
+ }
}
#ifdef CONFIG_STUBDOM
++++++ ioemu-disable-scsi.patch ++++++
---
tools/qemu-xen-traditional-dir-remote/hw/pci.c | 44 ++++++++++++++++
tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c | 2
tools/qemu-xen-traditional-dir-remote/qemu-xen.h | 1
3 files changed, 47 insertions(+)
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pci.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pci.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pci.c
@@ -871,6 +871,50 @@ void pci_unplug_netifs(void)
}
}
+void pci_unplug_scsi(void)
+{
+ PCIBus *bus;
+ PCIDevice *dev;
+ PCIIORegion *region;
+ int x;
+ int i;
+
+ /* We only support one PCI bus */
+ for (bus = first_bus; bus; bus = NULL) {
+ for (x = 0; x < 256; x++) {
+ dev = bus->devices[x];
+ if (dev &&
+ dev->config[0xa] == 0 &&
+ dev->config[0xb] == 1
+#ifdef CONFIG_PASSTHROUGH
+ && test_pci_devfn(x) != 1
+#endif
+ ) {
+ /* Found a scsi disk. Remove it from the bus. Note that
+ we don't free it here, since there could still be
+ references to it floating around. There are only
+ ever one or two structures leaked, and it's not
+ worth finding them all. */
+ bus->devices[x] = NULL;
+ for (i = 0; i < PCI_NUM_REGIONS; i++) {
+ region = &dev->io_regions[i];
+ if (region->addr == (uint32_t)-1 ||
+ region->size == 0)
+ continue;
+ fprintf(logfile, "region type %d at [%x,%x).\n",
+ region->type, region->addr,
+ region->addr+region->size);
+ if (region->type == PCI_ADDRESS_SPACE_IO) {
+ isa_unassign_ioport(region->addr, region->size);
+ } else if (region->type == PCI_ADDRESS_SPACE_MEM) {
+ unregister_iomem(region->addr);
+ }
+ }
+ }
+ }
+ }
+}
+
typedef struct {
PCIDevice dev;
PCIBus *bus;
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
@@ -364,6 +364,8 @@ static void suse_platform_ioport_write(v
* If it controlled just disk or just LAN, it would use 8 below. */
fprintf(logfile, "Disconnect IDE hard disk...\n");
ide_unplug_harddisks();
+ fprintf(logfile, "Disconnect SCSI hard disk...\n");
+ pci_unplug_scsi();
fprintf(logfile, "Disconnect netifs...\n");
pci_unplug_netifs();
fprintf(logfile, "Shutdown taps...\n");
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
@@ -47,6 +47,7 @@ void unset_vram_mapping(void *opaque);
#endif
void pci_unplug_netifs(void);
+void pci_unplug_scsi(void);
void destroy_hvm_domain(void);
void unregister_iomem(target_phys_addr_t start);
++++++ ioemu-hvm-pv-support.patch ++++++
---
tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c | 46 ++++++++++++++++
1 file changed, 46 insertions(+)
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
@@ -30,6 +30,8 @@
#include "qemu-xen.h"
#include "net.h"
#include "xen_platform.h"
+#include "sysemu.h"
+#include
#include
#include
@@ -335,8 +337,52 @@ static void xen_platform_ioport_writeb(v
}
}
+static uint32_t ioport_base;
+
+static void suse_platform_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+ DECLARE_DOMCTL;
+ int rc;
+
+ if (val == 0)
+ qemu_invalidate_map_cache();
+
+ switch (addr - ioport_base) {
+ case 0:
+ /* FIXME Unknown who makes use of this code! */
+ fprintf(logfile, "Init hypercall page %x, addr %x.\n", val, addr);
+ domctl.domain = (domid_t)domid;
+ domctl.u.hypercall_init.gmfn = val;
+ domctl.cmd = XEN_DOMCTL_hypercall_init;
+ rc = xc_domctl(xc_handle, &domctl);
+ fprintf(logfile, "result -> %d.\n", rc);
+ break;
+ case 4:
+ /* xen-kmp used this since xen-3.0.4, instead the official protocol from xen-3.3+
+ * pre vmdp 1.7 made use of 4 and 8 depending on how vmdp was configured.
+ * If vmdp was to control both disk and LAN it would use 4.
+ * If it controlled just disk or just LAN, it would use 8 below. */
+ fprintf(logfile, "Disconnect IDE hard disk...\n");
+ ide_unplug_harddisks();
+ fprintf(logfile, "Disconnect netifs...\n");
+ pci_unplug_netifs();
+ fprintf(logfile, "Shutdown taps...\n");
+ net_tap_shutdown_all();
+ fprintf(logfile, "Done.\n");
+ break;
+ default:
+ fprintf(logfile, "Write %x to bad port %x (base %x) on evtchn device.\n",
+ val, addr, ioport_base);
+ break;
+ }
+}
+
static void platform_ioport_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type)
{
+ ioport_base = addr;
+
+ register_ioport_write(addr, 16, 4, suse_platform_ioport_write, NULL);
+
PCIXenPlatformState *d = (PCIXenPlatformState *)pci_dev;
register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
++++++ ioemu-vnc-resize.patch ++++++
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
@@ -1751,6 +1751,25 @@ static int protocol_client_msg(VncState
}
set_encodings(vs, (int32_t *)(data + 4), limit);
+
+ /*
+ * The initialization of a VNC connection can race with xenfb changing
+ * the resolution. This happens when the VNC connection is already
+ * established, but the client has not yet advertised has_resize, so it
+ * won't get notified of the switch.
+ *
+ * Therefore we resend the resolution as soon as the client has sent its
+ * encodings.
+ */
+ if (vs->has_resize) {
+ /* Resize the VNC window */
+ vnc_write_u8(vs, 0); /* msg id */
+ vnc_write_u8(vs, 0);
+ vnc_write_u16(vs, 1); /* number of rects */
+ vnc_framebuffer_update(vs, 0, 0, vs->serverds.width, vs->serverds.height, -223);
+
+ vnc_flush(vs);
+ }
break;
case 3:
if (len == 1)
++++++ ioemu-watchdog-ib700-timer.patch ++++++
Subject: qdev: convert watchdogs
From: Markus Armbruster armbru@redhat.com Fri Aug 21 10:31:34 2009 +0200
Date: Thu Aug 27 20:35:24 2009 -0500:
Git: 09aaa1602f9381c0e0fb539390b1793e51bdfc7b
* THIS IS ONLY THE BUG FIX PART OF THE UPSTREAM PATCH *
Fixes ib700 not to use vm_clock before it is initialized: in
wdt_ib700_init(), called from register_watchdogs(), which runs before
init_timers(). The bug made ib700_write_enable_reg() crash in
qemu_del_timer().
Signed-off-by: Markus Armbruster
Signed-off-by: Anthony Liguori
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/wdt_ib700.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/wdt_ib700.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/wdt_ib700.c
@@ -93,6 +93,7 @@ static int ib700_load(QEMUFile *f, void
/* Create and initialize a virtual IB700 during PC creation. */
static void ib700_pc_init(PCIBus *unused)
{
+ timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL);
register_savevm("ib700_wdt", -1, 0, ib700_save, ib700_load, NULL);
register_ioport_write(0x441, 2, 1, ib700_write_disable_reg, NULL);
@@ -108,5 +109,4 @@ static WatchdogTimerModel model = {
void wdt_ib700_init(void)
{
watchdog_add_model(&model);
- timer = qemu_new_timer(vm_clock, ib700_timer_expired, NULL);
}
++++++ ioemu-watchdog-linkage.patch ++++++
Subject: Move watchdog, watchdog_action, give them internal linkage
From: Markus Armbruster armbru@redhat.com Fri Aug 21 10:31:32 2009 +0200
Date: Thu Aug 27 20:30:23 2009 -0500:
Git: 88b3be201acf64e0bd19782bebd533901c951c87
Signed-off-by: Markus Armbruster
Signed-off-by: Anthony Liguori
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/watchdog.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.c
@@ -26,6 +26,16 @@
#include "sysemu.h"
#include "hw/watchdog.h"
+/* Possible values for action parameter. */
+#define WDT_RESET 1 /* Hard reset. */
+#define WDT_SHUTDOWN 2 /* Shutdown. */
+#define WDT_POWEROFF 3 /* Quit. */
+#define WDT_PAUSE 4 /* Pause. */
+#define WDT_DEBUG 5 /* Prints a message and continues running. */
+#define WDT_NONE 6 /* Do nothing. */
+
+static WatchdogTimerModel *watchdog;
+static int watchdog_action = WDT_RESET;
static LIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
void watchdog_add_model(WatchdogTimerModel *model)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.h
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/watchdog.h
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.h
@@ -27,13 +27,6 @@
extern void wdt_i6300esb_init(void);
extern void wdt_ib700_init(void);
-/* Possible values for action parameter. */
-#define WDT_RESET 1 /* Hard reset. */
-#define WDT_SHUTDOWN 2 /* Shutdown. */
-#define WDT_POWEROFF 3 /* Quit. */
-#define WDT_PAUSE 4 /* Pause. */
-#define WDT_DEBUG 5 /* Prints a message and continues running. */
-#define WDT_NONE 6 /* Do nothing. */
struct WatchdogTimerModel {
LIST_ENTRY(WatchdogTimerModel) entry;
@@ -50,10 +43,6 @@ struct WatchdogTimerModel {
};
typedef struct WatchdogTimerModel WatchdogTimerModel;
-/* in vl.c */
-extern WatchdogTimerModel *watchdog;
-extern int watchdog_action;
-
/* in hw/watchdog.c */
extern int select_watchdog(const char *p);
extern int select_watchdog_action(const char *action);
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vl.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
@@ -250,8 +250,6 @@ int no_shutdown = 0;
int cursor_hide = 1;
int graphic_rotate = 0;
int daemonize = 0;
-WatchdogTimerModel *watchdog = NULL;
-int watchdog_action = WDT_RESET;
const char *option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;
++++++ ioemu-watchdog-support.patch ++++++
++++ 963 lines (skipped)
++++++ ipxe-enable-nics.patch ++++++
Index: xen-4.2.0-testing/tools/firmware/etherboot/Config
===================================================================
--- xen-4.2.0-testing.orig/tools/firmware/etherboot/Config
+++ xen-4.2.0-testing/tools/firmware/etherboot/Config
@@ -1,3 +1,4 @@
+NICS = rtl8139 8086100e eepro100 e1000 pcnet32 10ec8029
CFLAGS += -UPXE_DHCP_STRICT
CFLAGS += -DPXE_DHCP_STRICT
++++++ kernel-boot-hvm.patch ++++++
Direct kernel boot to HVM guests has regression from xen-3.3 to xen-4.0.
Foreport this feature to latest qemu-xen. Make a fake boot sector with given
kernel and initrd, which could be accessed by hvmloader.
Signed-off-by: Chunyan Liu
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.c
@@ -596,6 +596,16 @@ int bdrv_read(BlockDriverState *bs, int6
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
+
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(buf, bs->boot_sector_data, 512);
+ sector_num++;
+ nb_sectors--;
+ buf += 512;
+ if (nb_sectors == 0)
+ return 0;
+ }
+
if (drv->bdrv_pread) {
int ret, len;
len = nb_sectors * 512;
@@ -631,6 +641,10 @@ int bdrv_write(BlockDriverState *bs, int
if (bdrv_check_request(bs, sector_num, nb_sectors))
return -EIO;
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(bs->boot_sector_data, buf, 512);
+ }
+
if (drv->bdrv_pwrite) {
int ret, len, count = 0;
len = nb_sectors * 512;
@@ -934,6 +948,16 @@ void bdrv_guess_geometry(BlockDriverStat
}
}
+/* force a given boot sector. */
+void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
+{
+ bs->boot_sector_enabled = 1;
+ if (size > 512)
+ size = 512;
+ memcpy(bs->boot_sector_data, data, size);
+ memset(bs->boot_sector_data + size, 0, 512 - size);
+}
+
void bdrv_set_geometry_hint(BlockDriverState *bs,
int cyls, int heads, int secs)
{
@@ -1464,6 +1488,14 @@ BlockDriverAIOCB *bdrv_aio_read(BlockDri
if (bdrv_check_request(bs, sector_num, nb_sectors))
return NULL;
+ /* XXX: we assume that nb_sectors == 0 is suppored by the async read */
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(buf, bs->boot_sector_data, 512);
+ sector_num++;
+ nb_sectors--;
+ buf += 512;
+ }
+
ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
if (ret) {
@@ -1489,6 +1521,10 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDr
if (bdrv_check_request(bs, sector_num, nb_sectors))
return NULL;
+ if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
+ memcpy(bs->boot_sector_data, buf, 512);
+ }
+
ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
if (ret) {
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block_int.h
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block_int.h
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block_int.h
@@ -122,6 +122,9 @@ struct BlockDriverState {
BlockDriver *drv; /* NULL means no media */
void *opaque;
+ int boot_sector_enabled;
+ uint8_t boot_sector_data[512];
+
char filename[1024];
char backing_file[1024]; /* if non zero, the image is a diff of
this file image */
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pc.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c
@@ -474,45 +474,28 @@ static void bochs_bios_init(void)
/* Generate an initial boot sector which sets state and jump to
a specified vector */
-static void generate_bootsect(uint8_t *option_rom,
- uint32_t gpr[8], uint16_t segs[6], uint16_t ip)
+static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip)
{
- uint8_t rom[512], *p, *reloc;
- uint8_t sum;
+ uint8_t bootsect[512], *p;
int i;
+ int hda;
+
+ hda = drive_get_index(IF_IDE, 0, 0);
+ if (hda == -1) {
+ fprintf(stderr, "A disk image must be given for 'hda' when booting "
+ "a Linux kernel\n(if you really don't want it, use /dev/zero)\n");
+ exit(1);
+ }
+ memset(bootsect, 0, sizeof(bootsect));
- memset(rom, 0, sizeof(rom));
-
- p = rom;
- /* Make sure we have an option rom signature */
- *p++ = 0x55;
- *p++ = 0xaa;
-
- /* ROM size in sectors*/
- *p++ = 1;
-
- /* Hook int19 */
-
- *p++ = 0x50; /* push ax */
- *p++ = 0x1e; /* push ds */
- *p++ = 0x31; *p++ = 0xc0; /* xor ax, ax */
- *p++ = 0x8e; *p++ = 0xd8; /* mov ax, ds */
-
- *p++ = 0xc7; *p++ = 0x06; /* movvw _start,0x64 */
- *p++ = 0x64; *p++ = 0x00;
- reloc = p;
- *p++ = 0x00; *p++ = 0x00;
-
- *p++ = 0x8c; *p++ = 0x0e; /* mov cs,0x66 */
- *p++ = 0x66; *p++ = 0x00;
-
- *p++ = 0x1f; /* pop ds */
- *p++ = 0x58; /* pop ax */
- *p++ = 0xcb; /* lret */
-
- /* Actual code */
- *reloc = (p - rom);
+ /* Copy the MSDOS partition table if possible */
+ bdrv_read(drives_table[hda].bdrv, 0, bootsect, 1);
+ /* Make sure we have a partition signature */
+ bootsect[510] = 0x55;
+ bootsect[511] = 0xaa;
+ /* Actual code */
+ p = bootsect;
*p++ = 0xfa; /* CLI */
*p++ = 0xfc; /* CLD */
@@ -542,13 +525,7 @@ static void generate_bootsect(uint8_t *o
*p++ = segs[1]; /* CS */
*p++ = segs[1] >> 8;
- /* sign rom */
- sum = 0;
- for (i = 0; i < (sizeof(rom) - 1); i++)
- sum += rom[i];
- rom[sizeof(rom) - 1] = -sum;
-
- memcpy(option_rom, rom, sizeof(rom));
+ bdrv_set_boot_sector(drives_table[hda].bdrv, bootsect, sizeof(bootsect));
}
static long get_file_size(FILE *f)
@@ -565,8 +542,7 @@ static long get_file_size(FILE *f)
return size;
}
-static void load_linux(uint8_t *option_rom,
- const char *kernel_filename,
+static void load_linux(const char *kernel_filename,
const char *initrd_filename,
const char *kernel_cmdline)
{
@@ -632,7 +608,9 @@ static void load_linux(uint8_t *option_r
/* Special pages are placed at end of low RAM: pick an arbitrary one and
* subtract a suitably large amount of padding (64kB) to skip BIOS data. */
- xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram);
+ //xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &end_low_ram);
+ /* BUFIO Page beyond last_pfn, use 0x7ffc instead. Fix ME. */
+ end_low_ram = 0x7ffc;
end_low_ram = (end_low_ram << 12) - (64*1024);
/* highest address for loading the initrd */
@@ -721,7 +699,7 @@ static void load_linux(uint8_t *option_r
memset(gpr, 0, sizeof gpr);
gpr[4] = cmdline_addr-real_addr-16; /* SP (-16 is paranoia) */
- generate_bootsect(option_rom, gpr, seg, 0);
+ generate_bootsect(gpr, seg, 0);
#endif
}
@@ -932,14 +910,6 @@ vga_bios_error:
int size, offset;
offset = 0;
- if (linux_boot) {
- option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE);
- load_linux(phys_ram_base + option_rom_offset,
- kernel_filename, initrd_filename, kernel_cmdline);
- cpu_register_physical_memory(0xd0000, TARGET_PAGE_SIZE,
- option_rom_offset | IO_MEM_ROM);
- offset = TARGET_PAGE_SIZE;
- }
for (i = 0; i < nb_option_roms; i++) {
size = get_image_size(option_rom[i]);
@@ -973,6 +943,9 @@ vga_bios_error:
bochs_bios_init();
+ if (linux_boot)
+ load_linux(kernel_filename, initrd_filename, kernel_cmdline);
+
cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
i8259 = i8259_init(cpu_irq[0]);
ferr_irq = i8259[13];
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.h
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block.h
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/block.h
@@ -82,6 +82,7 @@ int64_t bdrv_getlength(BlockDriverState
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs);
int bdrv_commit(BlockDriverState *bs);
+void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
/* async block I/O */
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
typedef void BlockDriverCompletionFunc(void *opaque, int ret);
++++++ kmp_filelist ++++++
%defattr (-,root,root)
/lib/modules/%2-%1
++++++ libxc-pass-errno-to-callers-of-xc_domain_save.patch ++++++
++++ 647 lines (skipped)
++++++ libxen_permissive.patch ++++++
Index: xen-4.2.0-testing/tools/libxen/src/xen_common.c
===================================================================
--- xen-4.2.0-testing.orig/tools/libxen/src/xen_common.c
+++ xen-4.2.0-testing/tools/libxen/src/xen_common.c
@@ -904,8 +904,15 @@ static void parse_into(xen_session *s, x
0 != strcmp((char *)value_node->children->name, "struct") ||
value_node->children->children == NULL)
{
+#if PERMISSIVE
+ fprintf(stderr,
+ "Expected Map from the server, but didn't get one\n");
+ ((arbitrary_map **)value)[slot] = NULL;
+#else
+
server_error(s,
"Expected Map from the server, but didn't get it");
+#endif
}
else
{
++++++ libxl-migration-cleanup-remove-backend-domain-field.patch ++++++
References: bnc#903359
Remove the unusual 'domain' field under backend directory. The
affected are backend/console, backend/vfb, backend/vkbd.
Signed-off-by: Chunyan Liu
---
tools/libxl/libxl.c | 5 -----
1 file changed, 5 deletions(-)
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -3519,8 +3519,6 @@ int libxl__device_console_add(libxl__gc
flexarray_append(back, "1");
flexarray_append(back, "state");
flexarray_append(back, libxl__sprintf(gc, "%d", 1));
- flexarray_append(back, "domain");
- flexarray_append(back, libxl__domid_to_name(gc, domid));
flexarray_append(back, "protocol");
flexarray_append(back, LIBXL_XENCONSOLE_PROTOCOL);
@@ -3630,8 +3628,6 @@ int libxl__device_vkb_add(libxl__gc *gc,
flexarray_append(back, "1");
flexarray_append(back, "state");
flexarray_append(back, libxl__sprintf(gc, "%d", 1));
- flexarray_append(back, "domain");
- flexarray_append(back, libxl__domid_to_name(gc, domid));
flexarray_append(front, "backend-id");
flexarray_append(front, libxl__sprintf(gc, "%d", vkb->backend_domid));
@@ -3728,7 +3724,6 @@ int libxl__device_vfb_add(libxl__gc *gc,
flexarray_append_pair(back, "frontend-id", libxl__sprintf(gc, "%d", domid));
flexarray_append_pair(back, "online", "1");
flexarray_append_pair(back, "state", libxl__sprintf(gc, "%d", 1));
- flexarray_append_pair(back, "domain", libxl__domid_to_name(gc, domid));
flexarray_append_pair(back, "vnc",
libxl_defbool_val(vfb->vnc.enable) ? "1" : "0");
flexarray_append_pair(back, "vnclisten", vfb->vnc.listen);
++++++ libxl-migration-cleanup-update-uuid-name.patch ++++++
References: bnc#903359
libxl__domain_rename only updates /local/domain/<domid>/name,
/vm/<uuid>/name in xenstore are not updated. Add code in
libxl__domain_rename to update /vm/<uuid>/name too.
Signed-off-by: Chunyan Liu
---
tools/libxl/libxl.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -291,6 +291,9 @@ int libxl__domain_rename(libxl__gc *gc,
uint32_t stub_dm_domid;
const char *stub_dm_old_name = NULL, *stub_dm_new_name = NULL;
int rc;
+ libxl_dominfo info;
+ char *uuid;
+ const char *vm_name_path;
dom_path = libxl__xs_get_dompath(gc, domid);
if (!dom_path) goto x_nomem;
@@ -361,6 +364,16 @@ int libxl__domain_rename(libxl__gc *gc,
goto x_fail;
}
+ /* update /vm/<uuid>/name */
+ rc = libxl_domain_info(ctx, &info, domid);
+ if (rc)
+ goto x_fail;
+
+ uuid = GCSPRINTF(LIBXL_UUID_FMT, LIBXL_UUID_BYTES(info.uuid));
+ vm_name_path = GCSPRINTF("/vm/%s/name", uuid);
+ if (libxl__xs_write_checked(gc, trans, vm_name_path, new_name))
+ goto x_fail;
+
if (stub_dm_domid) {
rc = libxl__domain_rename(gc, stub_dm_domid,
stub_dm_old_name,
++++++ libxl-restore-cleanup-left-xenstore-entries.patch ++++++
From 92f8d0e968f128445cb43569ecef0e131a8c077c Mon Sep 17 00:00:00 2001
From: Chunyan Liu
Date: Tue, 18 Nov 2014 17:10:58 +0800
Subject: [PATCH] fix restore: xenstore entries left when restore failed
While running libvirt-tck domain/102-broken-save-restore.t
test (save domain, corrupt saved file by truncate the last 512k,
then restore), found that restore domain failed, but domain
related xenstore entries still exist in xenstore.
Add a patch to clear xenstore entries in this case.
Signed-off-by: Chunyan Liu
---
tools/libxl/libxl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -1414,6 +1414,54 @@ static void devices_destroy_cb(libxl__eg
libxl__devices_remove_state *drs,
int rc);
+static void libxl_clear_xs_entry(libxl__gc *gc, uint32_t domid)
+{
+ const char *dom_path, *vm_path;
+ char *path;
+ unsigned int num_kinds, num_dev_xsentries;
+ char **kinds = NULL, **devs = NULL;
+ int i, j;
+
+ /* remove libxl path */
+ libxl__xs_rm_checked(gc, XBT_NULL, libxl__xs_libxl_path(gc, domid));
+
+ dom_path = libxl__xs_get_dompath(gc, domid);
+ if (!dom_path)
+ return;
+
+ /* remove backend entries */
+ path = GCSPRINTF("%s/device", dom_path);
+ kinds = libxl__xs_directory(gc, XBT_NULL, path, &num_kinds);
+ if (kinds && num_kinds) {
+ for (i = 0; i < num_kinds; i++) {
+ path = GCSPRINTF("%s/device/%s", dom_path, kinds[i]);
+ devs = libxl__xs_directory(gc, XBT_NULL, path, &num_dev_xsentries);
+ if (!devs)
+ continue;
+ for (j = 0; j < num_dev_xsentries; j++) {
+ path = GCSPRINTF("%s/device/%s/%s/backend",
+ dom_path, kinds[i], devs[j]);
+ path = libxl__xs_read(gc, XBT_NULL, path);
+ if (path)
+ libxl__xs_rm_checked(gc, XBT_NULL, path);
+ }
+ }
+ }
+
+ path = GCSPRINTF("%s/console/backend", dom_path);
+ path = libxl__xs_read(gc, XBT_NULL, path);
+ if (path)
+ libxl__xs_rm_checked(gc, XBT_NULL, path);
+
+ /* remove vm path */
+ vm_path = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/vm", dom_path));
+ if (vm_path)
+ libxl__xs_rm_checked(gc, XBT_NULL, vm_path);
+
+ /* remove dom path */
+ libxl__xs_rm_checked(gc, XBT_NULL, dom_path);
+}
+
void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
{
STATE_AO_GC(dis->ao);
@@ -1429,6 +1477,10 @@ void libxl__destroy_domid(libxl__egc *eg
break;
case ERROR_INVAL:
LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "non-existant domain %d", domid);
+ /* domain may not started successfully but some xenstore entries
+ * might be created already in earlier stage. We need to clear
+ * those entries. */
+ libxl_clear_xs_entry(gc, domid);
default:
goto out;
}
++++++ libxl.add-option-for-discard-support-to-xl-disk-conf.patch ++++++
References: FATE#316071
Subject: libxl: add option for discard support to xl disk configuration
Handle new boolean option discard/no-discard for disk configuration. It
is supposed to disable discard support if file based backing storage was
intentionally created non-sparse to avoid fragmentation of the file.
The option intended for the backend driver. A new boolean property
"discard-enable" is written to the backend node. An upcoming patch for
qemu will make use of this property. The kernel blkback driver may be
updated as well to disable discard for phy based backing storage.
This change does not break ABI. Instead of adding a new member
discard_enable to struct libxl_device_disk the existing readwrite member
is reused.
Signed-off-by: Olaf Hering
---
docs/misc/xl-disk-configuration.txt | 17 +++++++++++++++++
tools/libxl/libxl.c | 2 ++
tools/libxl/libxl.h | 12 ++++++++++++
tools/libxl/libxlu_disk.c | 3 +++
tools/libxl/libxlu_disk_i.h | 2 +-
tools/libxl/libxlu_disk_l.l | 2 ++
6 files changed, 37 insertions(+), 1 deletion(-)
Index: xen-4.4.3-testing/docs/misc/xl-disk-configuration.txt
===================================================================
--- xen-4.4.3-testing.orig/docs/misc/xl-disk-configuration.txt
+++ xen-4.4.3-testing/docs/misc/xl-disk-configuration.txt
@@ -179,6 +179,23 @@ These scripts are normally called "block
+discard / no-discard
+---------------
+
+Description: Request backend to advertise discard support to frontend
+Supported values: discard
+ no-discard
+Mandatory: No
+Default value: discard
+
+An advisory setting for the backend driver, specifying whether, to
+advertise discard support (TRIM, UNMAP) to the frontend. The real
+benefit of this option is to be able to force it off rather than on. It
+can be used to disable "hole punching" for file based backends which
+were intentionally created non-sparse to avoid fragmentation of the
+file.
+
+
============================================
DEPRECATED PARAMETERS, PREFIXES AND SYNTAXES
============================================
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -2497,6 +2497,8 @@ static void device_disk_add(libxl__egc *
flexarray_append(back, disk->readwrite ? "w" : "r");
flexarray_append(back, "device-type");
flexarray_append(back, disk->is_cdrom ? "cdrom" : "disk");
+ if ((disk->readwrite & ~LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK) == LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MAGIC)
+ flexarray_append_pair(back, "discard-enable", "0");
flexarray_append(front, "backend-id");
flexarray_append(front, libxl__sprintf(gc, "%d", disk->backend_domid));
Index: xen-4.4.3-testing/tools/libxl/libxl.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.h
+++ xen-4.4.3-testing/tools/libxl/libxl.h
@@ -95,6 +95,18 @@
#define LIBXL_HAVE_BUILDINFO_EVENT_CHANNELS 1
/*
+ * The libxl_device_disk lacks discard_enable field, disabling discard
+ * is supported without breaking the ABI. This is done by overloading
+ * struct libxl_device_disk->readwrite:
+ * readwrite == 0: disk is readonly, no discard
+ * readwrite == 1: disk is readwrite, backend driver may enable discard
+ * readwrite == MAGIC: disk is readwrite, backend driver should not offer
+ * discard to the frontend driver.
+ */
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MAGIC 0x00000060U
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK 0xffffff0fU
+
+/*
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk.c
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk.c
@@ -80,6 +80,9 @@ int xlu_disk_parse(XLU_Config *cfg,
disk->format = LIBXL_DISK_FORMAT_EMPTY;
}
+ if (disk->readwrite && dpc.disable_discard)
+ disk->readwrite = (disk->readwrite & LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK) | LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MAGIC;
+
if (!disk->vdev) {
xlu__disk_err(&dpc,0, "no vdev specified");
goto x_err;
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk_i.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk_i.h
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk_i.h
@@ -10,7 +10,7 @@ typedef struct {
void *scanner;
YY_BUFFER_STATE buf;
libxl_device_disk *disk;
- int access_set, had_depr_prefix;
+ int access_set, disable_discard, had_depr_prefix;
const char *spec;
} DiskParseContext;
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk_l.l
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk_l.l
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk_l.l
@@ -173,6 +173,8 @@ backendtype=[^,]*,? { STRIP(','); setbac
vdev=[^,]*,? { STRIP(','); SAVESTRING("vdev", vdev, FROMEQUALS); }
script=[^,]*,? { STRIP(','); SAVESTRING("script", script, FROMEQUALS); }
+discard,? { DPC->disable_discard = 0; }
+no-discard,? { DPC->disable_discard = 1; }
/* the target magic parameter, eats the rest of the string */
++++++ libxl.add-option-to-disable-disk-cache-flushes-in-qdisk.patch ++++++
https://bugzilla.novell.com/show_bug.cgi?id=879425
---
tools/libxl/libxl.c | 2 ++
tools/libxl/libxl.h | 12 ++++++++++++
tools/libxl/libxlu_disk.c | 2 ++
tools/libxl/libxlu_disk_i.h | 2 +-
tools/libxl/libxlu_disk_l.l | 1 +
5 files changed, 18 insertions(+), 1 deletion(-)
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -2501,6 +2501,8 @@ static void device_disk_add(libxl__egc *
flexarray_append_pair(back, "direct-io-safe", "1");
if ((disk->readwrite & ~LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK) == LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MAGIC)
flexarray_append_pair(back, "discard-enable", "0");
+ if ((disk->readwrite & ~LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MASK) == LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MAGIC)
+ flexarray_append_pair(back, "suse-diskcache-disable-flush", "1");
flexarray_append(front, "backend-id");
flexarray_append(front, libxl__sprintf(gc, "%d", disk->backend_domid));
Index: xen-4.4.3-testing/tools/libxl/libxl.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.h
+++ xen-4.4.3-testing/tools/libxl/libxl.h
@@ -118,6 +118,18 @@
#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK 0xffffff0fU
/*
+ * The libxl_device_disk has no way to indicate that cache=unsafe is
+ * supposed to be used. Provide this knob without breaking the ABI.
+ * This is done by overloading struct libxl_device_disk->readwrite:
+ * readwrite == 0: disk is readonly, no discard
+ * readwrite == 1: disk is readwrite, backend driver may enable discard
+ * readwrite == MAGIC: disk is readwrite, backend driver should ignore
+ * flush requests from the frontend driver.
+ */
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MAGIC 0x00006000U
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MASK 0xffff0fffU
+
+/*
* libxl ABI compatibility
*
* The only guarantee which libxl makes regarding ABI compatibility
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk.c
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk.c
@@ -84,6 +84,8 @@ int xlu_disk_parse(XLU_Config *cfg,
disk->readwrite = (disk->readwrite & LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MASK) | LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MAGIC;
if (disk->readwrite && dpc.disable_discard)
disk->readwrite = (disk->readwrite & LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK) | LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MAGIC;
+ if (disk->readwrite && dpc.suse_diskcache_disable_flush)
+ disk->readwrite = (disk->readwrite & LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MASK) | LIBXL_HAVE_LIBXL_DEVICE_DISK_DISABLE_FLUSH_MAGIC;
if (!disk->vdev) {
xlu__disk_err(&dpc,0, "no vdev specified");
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk_i.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk_i.h
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk_i.h
@@ -10,7 +10,7 @@ typedef struct {
void *scanner;
YY_BUFFER_STATE buf;
libxl_device_disk *disk;
- int access_set, direct_io_safe, disable_discard, had_depr_prefix;
+ int access_set, suse_diskcache_disable_flush, direct_io_safe, disable_discard, had_depr_prefix;
const char *spec;
} DiskParseContext;
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk_l.l
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk_l.l
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk_l.l
@@ -176,6 +176,7 @@ script=[^,]*,? { STRIP(','); SAVESTRING(
direct-io-safe,? { DPC->direct_io_safe = 1; }
discard,? { DPC->disable_discard = 0; }
no-discard,? { DPC->disable_discard = 1; }
+suse-diskcache-disable-flush,? { DPC->suse_diskcache_disable_flush = 1; }
/* the target magic parameter, eats the rest of the string */
++++++ libxl.honor-more-top-level-vfb-options.patch ++++++
From: Wei Liu
Date: Tue, 28 Jan 2014 15:38:01 +0000
Subject: xl: honor more top level vfb options
Now that SDL and keymap options for VFB can also be specified in top
level options. Documentation is also updated.
This fixes bug #31 and further possible problems.
Signed-off-by: Wei Liu
Cc: Olaf Hering
Cc: Ian Campbell
Cc: Ian Jackson
---
docs/man/xl.cfg.pod.5 | 4 ++--
tools/libxl/xl_cmdimpl.c | 17 ++++++++++++++---
2 files changed, 16 insertions(+), 5 deletions(-)
Index: xen-4.4.2-testing/docs/man/xl.cfg.pod.5
===================================================================
--- xen-4.4.2-testing.orig/docs/man/xl.cfg.pod.5
+++ xen-4.4.2-testing/docs/man/xl.cfg.pod.5
@@ -420,8 +420,8 @@ This options does not control the emulat
an HVM guest. See L<Emulated VGA Graphics Device> below for how to
configure the emulated device. If L<Emulated VGA Graphics Device> options
are used in a PV guest configuration, xl will pick up B<vnc>, B<vnclisten>,
-B<vncpasswd>, B<vncdisplay> and B<vncunused> to construct paravirtual
-framebuffer device for the guest.
+B<vncpasswd>, B<vncdisplay>, B<vncunused>, B<sdl>, B<opengl> and
+B<keymap> to construct paravirtual framebuffer device for the guest.
Each B is a comma-separated list of C
settings, from the following list:
Index: xen-4.4.2-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.4.2-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.4.2-testing/tools/libxl/xl_cmdimpl.c
@@ -744,6 +744,15 @@ static char *parse_cmdline(XLU_Config *c
return cmdline;
}
+static void parse_top_level_sdl_options(XLU_Config *config,
+ libxl_sdl_info *sdl)
+{
+ xlu_cfg_get_defbool(config, "sdl", &sdl->enable, 0);
+ xlu_cfg_get_defbool(config, "opengl", &sdl->opengl, 0);
+ xlu_cfg_replace_string (config, "display", &sdl->display, 0);
+ xlu_cfg_replace_string (config, "xauthority", &sdl->xauthority, 0);
+}
+
static void parse_config_data(const char *config_source,
const char *config_data,
int config_len,
@@ -1666,9 +1675,13 @@ skip_vfb:
libxl_device_vkb_init);
parse_top_level_vnc_options(config, &vfb->vnc);
+ parse_top_level_sdl_options(config, &vfb->sdl);
+ xlu_cfg_replace_string (config, "keymap", &vfb->keymap, 0);
}
- } else
+ } else {
parse_top_level_vnc_options(config, &b_info->u.hvm.vnc);
+ parse_top_level_sdl_options(config, &b_info->u.hvm.sdl);
+ }
if (c_info->type == LIBXL_DOMAIN_TYPE_HVM) {
if (!xlu_cfg_get_string (config, "vga", &buf, 0)) {
@@ -1689,8 +1702,6 @@ skip_vfb:
LIBXL_VGA_INTERFACE_TYPE_CIRRUS;
xlu_cfg_replace_string (config, "keymap", &b_info->u.hvm.keymap, 0);
- xlu_cfg_get_defbool(config, "sdl", &b_info->u.hvm.sdl.enable, 0);
- xlu_cfg_get_defbool(config, "opengl", &b_info->u.hvm.sdl.opengl, 0);
xlu_cfg_get_defbool (config, "spice", &b_info->u.hvm.spice.enable, 0);
if (!xlu_cfg_get_long (config, "spiceport", &l, 0))
b_info->u.hvm.spice.port = l;
++++++ libxl.introduce-an-option-to-disable-the-non-O_DIRECT-workaround.patch ++++++
xen-unstable commit 6ec48cf41b6656c98148380f39010063e62628c5
Frp,: Stefano Stabellini
Date: Wed Apr 30 16:06:24 2014 +0100
Subject: libxl: introduce an option for disabling the non-O_DIRECT workaround
Document and implement a new option that permits disk backends which
would otherwise have to avoid O_DIRECT (because of the network memory
lifetime bug) to use it anyway. This is:
direct-io-safe in the xl domain disk config specification
direct_io_safe in the libxl disk API
direct-io-safe in the backend xenstore interface
Add a reference to xen/include/public/io/blkif.h in
docs/misc/vbd-interface.txt.
This change does not break ABI. Instead of adding a new member
direct_io_safe to struct libxl_device_disk the existing readwrite member
is reused.
Signed-off-by: Stefano Stabellini
Signed-off-by: Ian Jackson
Acked-by: Ian Campbell
Tested-by: Felipe Franciosi
---
docs/misc/vbd-interface.txt | 6 +++++
docs/misc/xl-disk-configuration.txt | 38 ++++++++++++++++++++++++++++++++++++
tools/libxl/libxl.c | 2 +
tools/libxl/libxl.h | 11 ++++++++++
tools/libxl/libxlu_disk.c | 2 +
tools/libxl/libxlu_disk_i.h | 2 -
tools/libxl/libxlu_disk_l.l | 1
xen/include/public/io/blkif.h | 22 ++++++++++++++++++++
8 files changed, 83 insertions(+), 1 deletion(-)
Index: xen-4.4.3-testing/docs/misc/vbd-interface.txt
===================================================================
--- xen-4.4.3-testing.orig/docs/misc/vbd-interface.txt
+++ xen-4.4.3-testing/docs/misc/vbd-interface.txt
@@ -125,3 +125,9 @@ because they directly map the bottom 8 b
directly to the Linux guest's device number and throw away the rest;
they can crash due to minor number clashes. With these guests, the
workaround is not to supply problematic combinations of devices.
+
+
+Other frontend and backend options
+----------------------------------
+
+See xen/include/public/io/blkif.h for the full list of options.
Index: xen-4.4.3-testing/docs/misc/xl-disk-configuration.txt
===================================================================
--- xen-4.4.3-testing.orig/docs/misc/xl-disk-configuration.txt
+++ xen-4.4.3-testing/docs/misc/xl-disk-configuration.txt
@@ -178,6 +178,44 @@ information to be interpreted by the exe
These scripts are normally called "block-<script>".
+direct-io-safe
+--------------
+
+Description: Disables non-O_DIRECT workaround
+Supported values: absent, present
+Mandatory: No
+Default value: absent (workaround may be enabled)
+
+There is a memory lifetime bug in some driver domain (dom0) kernels
+which can cause crashes when using O_DIRECT. The bug occurs due to a
+mismatch between the backend-visible lifetime of pages used for the
+Xen PV network protocol and that expected by the backend kernel's
+networking subsystem. This can cause crashes when using certain
+backends with certain underlying storage.
+
+See:
+ http://lists.xen.org/archives/html/xen-devel/2012-12/msg01154.html
+
+For this reason, (this version of) the Xen libxl toolstack disables
+O_DIRECT when using the qemu-based Xen PV backend ("qdisk").
+
+However, this workaround has performance and scaling implications, and
+it is only necessary if the underlying device is a network filesystem.
+If the underlying device is not, then it is good to disable it; that
+is what this option is for.
+
+This option simply requests that the workaround be disabled. (However,
+not all backends versions which use the workaround understand this
+option, so this is on a best effort basis.)
+
+It's important to note that if you are storing the VM disk on a
+network filesystem or a network block device (NFS or ISCSI) it might
+not be safe to use this option. Otherwise specifying it is safe and
+can give better performances.
+
+If in the future the bug is fixed properly this option will then be
+silently ignored.
+
discard / no-discard
---------------
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -2497,6 +2497,8 @@ static void device_disk_add(libxl__egc *
flexarray_append(back, disk->readwrite ? "w" : "r");
flexarray_append(back, "device-type");
flexarray_append(back, disk->is_cdrom ? "cdrom" : "disk");
+ if ((disk->readwrite & ~LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MASK) == LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MAGIC)
+ flexarray_append_pair(back, "direct-io-safe", "1");
if ((disk->readwrite & ~LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK) == LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MAGIC)
flexarray_append_pair(back, "discard-enable", "0");
Index: xen-4.4.3-testing/tools/libxl/libxl.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.h
+++ xen-4.4.3-testing/tools/libxl/libxl.h
@@ -95,6 +95,17 @@
#define LIBXL_HAVE_BUILDINFO_EVENT_CHANNELS 1
/*
+ * The libxl_device_disk lacks some "cache" field, enabling directio
+ * is supported without breaking the ABI. This is done by overloading
+ * struct libxl_device_disk->readwrite:
+ * readwrite == 0: disk is readonly, no directio
+ * readwrite == 1: disk is readwrite, backend driver may enable directio
+ * readwrite == MAGIC: disk is readwrite, backend driver should use direct IO
+ */
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MAGIC 0x00000600U
+#define LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MASK 0xfffff0ffU
+
+/*
* The libxl_device_disk lacks discard_enable field, disabling discard
* is supported without breaking the ABI. This is done by overloading
* struct libxl_device_disk->readwrite:
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk.c
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk.c
@@ -80,6 +80,8 @@ int xlu_disk_parse(XLU_Config *cfg,
disk->format = LIBXL_DISK_FORMAT_EMPTY;
}
+ if (disk->readwrite && dpc.direct_io_safe)
+ disk->readwrite = (disk->readwrite & LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MASK) | LIBXL_HAVE_LIBXL_DEVICE_DISK_DIRECT_IO_SAFE_MAGIC;
if (disk->readwrite && dpc.disable_discard)
disk->readwrite = (disk->readwrite & LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MASK) | LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_DISABLE_MAGIC;
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk_i.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk_i.h
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk_i.h
@@ -10,7 +10,7 @@ typedef struct {
void *scanner;
YY_BUFFER_STATE buf;
libxl_device_disk *disk;
- int access_set, disable_discard, had_depr_prefix;
+ int access_set, direct_io_safe, disable_discard, had_depr_prefix;
const char *spec;
} DiskParseContext;
Index: xen-4.4.3-testing/tools/libxl/libxlu_disk_l.l
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxlu_disk_l.l
+++ xen-4.4.3-testing/tools/libxl/libxlu_disk_l.l
@@ -173,6 +173,7 @@ backendtype=[^,]*,? { STRIP(','); setbac
vdev=[^,]*,? { STRIP(','); SAVESTRING("vdev", vdev, FROMEQUALS); }
script=[^,]*,? { STRIP(','); SAVESTRING("script", script, FROMEQUALS); }
+direct-io-safe,? { DPC->direct_io_safe = 1; }
discard,? { DPC->disable_discard = 0; }
no-discard,? { DPC->disable_discard = 1; }
Index: xen-4.4.3-testing/xen/include/public/io/blkif.h
===================================================================
--- xen-4.4.3-testing.orig/xen/include/public/io/blkif.h
+++ xen-4.4.3-testing/xen/include/public/io/blkif.h
@@ -97,6 +97,28 @@
*
* The type of the backing device/object.
*
+ *
+ * direct-io-safe
+ * Values: 0/1 (boolean)
+ * Default Value: 0
+ *
+ * The underlying storage is not affected by the direct IO memory
+ * lifetime bug. See:
+ * http://lists.xen.org/archives/html/xen-devel/2012-12/msg01154.html
+ *
+ * Therefore this option gives the backend permission to use
+ * O_DIRECT, notwithstanding that bug.
+ *
+ * That is, if this option is enabled, use of O_DIRECT is safe,
+ * in circumstances where we would normally have avoided it as a
+ * workaround for that bug. This option is not relevant for all
+ * backends, and even not necessarily supported for those for
+ * which it is relevant. A backend which knows that it is not
+ * affected by the bug can ignore this option.
+ *
+ * This option doesn't require a backend to use O_DIRECT, so it
+ * should not be used to try to control the caching behaviour.
+ *
*--------------------------------- Features ---------------------------------
*
* feature-barrier
++++++ libxl.pvscsi.patch ++++++
++++ 1189 lines (skipped)
++++++ libxl.set-migration-constraints-from-cmdline.patch ++++++
From 77deb80879859ed279e24a790ec08e9c5d37dd0e Mon Sep 17 00:00:00 2001
From: Olaf Hering
Date: Wed, 5 Feb 2014 14:37:53 +0100
Subject: libxl: set migration constraints from cmdline
Add new options to xl migrate to control the process of migration.
The intention is to optionally abort the migration if it takes too long
to migrate a busy guest due to the high number of new dirty pages.
Currently the guest is suspended to transfer the remaining dirty pages.
The suspend/resume cycle will cause a time jump. This transfer can take
a long time, which can confuse the guest if the time jump is too far.
The new options allow to override the built-in default values, which are
not changed by this patch.
--max_iters <number> Number of iterations before final suspend (default: 30)
--max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM)
--min_remaing <pages> Number of dirty pages before stop© (default: 50)
--abort_if_busy Abort migration instead of doing final suspend.
The changes to libxl change the API, handle LIBXL_API_VERSION == 0x040200.
v8:
- merge --min_remaing changes
- tools/libxc: print stats if migration is aborted
- use special _suse version of lib calls to preserve ABI
v7:
- remove short options
- update description of --abort_if_busy in xl.1
- extend description of --abort_if_busy in xl help
- add comment to libxl_domain_suspend declaration, props is optional
v6:
- update the LIBXL_API_VERSION handling for libxl_domain_suspend
change it to an inline function if LIBXL_API_VERSION is defined to 4.2.0
- rename libxl_save_properties to libxl_domain_suspend_properties
- rename ->xlflags to ->flags within that struct
v5:
- adjust libxl_domain_suspend prototype, move flags, max_iters,
max_factor into a new, optional struct libxl_save_properties
- rename XCFLAGS_DOMSAVE_NOSUSPEND to XCFLAGS_DOMSAVE_ABORT_IF_BUSY
- rename LIBXL_SUSPEND_NO_FINAL_SUSPEND to LIBXL_SUSPEND_ABORT_IF_BUSY
- rename variables no_suspend to abort_if_busy
- rename option -N/--no_suspend to -A/--abort_if_busy
- update xl.1, extend description of -A option
v4:
- update default for no_suspend from None to 0 in XendCheckpoint.py:save
- update logoutput in setMigrateConstraints
- change xm migrate defaults from None to 0
- add new options to xl.1
- fix syntax error in XendDomain.py:domain_migrate_constraints_set
- fix xm migrate -N option name to match xl migrate
v3:
- move logic errors in libxl__domain_suspend and fixed help text in
cmd_table to separate patches
- fix syntax error in XendCheckpoint.py
- really pass max_iters and max_factor in libxl__xc_domain_save
- make libxl_domain_suspend_0x040200 declaration globally visible
- bump libxenlight.so SONAME from 2.0 to 2.1 due to changed
libxl_domain_suspend
v2:
- use LIBXL_API_VERSION and define libxl_domain_suspend_0x040200
- fix logic error in min_reached check in xc_domain_save
- add longopts
- update --help text
- correct description of migrate --help text
Signed-off-by: Olaf Hering
---
docs/man/xl.pod.1 | 20 +++++++++++++++++++
tools/libxc/xc_domain_save.c | 27 +++++++++++++++++++++++--
tools/libxc/xc_nomigrate.c | 10 +++++++++
tools/libxc/xenguest.h | 7 ++++++
tools/libxl/libxl.c | 27 ++++++++++++++++++++++---
tools/libxl/libxl.h | 15 ++++++++++++++
tools/libxl/libxl_dom.c | 1
tools/libxl/libxl_internal.h | 4 +++
tools/libxl/libxl_save_callout.c | 4 ++-
tools/libxl/libxl_save_helper.c | 4 ++-
tools/libxl/xl_cmdimpl.c | 41 +++++++++++++++++++++++++++++++++------
tools/libxl/xl_cmdtable.c | 23 ++++++++++++++-------
12 files changed, 162 insertions(+), 21 deletions(-)
Index: xen-4.4.3-testing/docs/man/xl.pod.1
===================================================================
--- xen-4.4.3-testing.orig/docs/man/xl.pod.1
+++ xen-4.4.3-testing/docs/man/xl.pod.1
@@ -392,6 +392,26 @@ Send <config> instead of config file fro
Print huge (!) amount of debug during the migration process.
+=item B<--max_iters> I<number>
+
+Number of iterations before final suspend (default: 30)
+
+=item B<--max_factor> I<factor>
+
+Max amount of memory to transfer before final suspend (default: 3*RAM)
+
+=item B<--min_remaining>
+
+Number of remaining dirty pages. If the number of dirty pages drops that
+low the guest is suspended and the remaing pages are transfered to <host>.
+
+=item B<--abort_if_busy>
+
+Abort migration instead of doing final suspend/transfer/resume if the
+guest has still dirty pages after the number of iterations and/or the
+amount of RAM transferred. This avoids long periods of time where the
+guest is suspended.
+
=back
=item B<remus> [I<OPTIONS>] I<domain-id> I<host>
Index: xen-4.4.3-testing/tools/libxc/xc_domain_save.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxc/xc_domain_save.c
+++ xen-4.4.3-testing/tools/libxc/xc_domain_save.c
@@ -43,6 +43,7 @@
*/
#define DEF_MAX_ITERS 29 /* limit us to 30 times round loop */
#define DEF_MAX_FACTOR 3 /* never send more than 3x p2m_size */
+#define DEF_MIN_REMAINING 50 /* low water mark of dirty pages */
struct save_ctx {
unsigned long hvirt_start; /* virtual starting address of the hypervisor */
@@ -798,8 +799,9 @@ static int save_tsc_info(xc_interface *x
return 0;
}
-int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
+int xc_domain_save_suse(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
uint32_t max_factor, uint32_t flags,
+ uint32_t min_remaining,
struct save_callbacks* callbacks, int hvm,
unsigned long vm_generationid_addr)
{
@@ -810,6 +812,7 @@ int xc_domain_save(xc_interface *xch, in
int rc = 1, frc, i, j, last_iter = 0, iter = 0;
int live = (flags & XCFLAGS_LIVE);
int debug = (flags & XCFLAGS_DEBUG);
+ int abort_if_busy = (flags & XCFLAGS_DOMSAVE_ABORT_IF_BUSY);
int superpages = !!hvm;
int race = 0, sent_last_iter, skip_this_iter = 0;
unsigned int sent_this_iter = 0;
@@ -910,6 +913,7 @@ int xc_domain_save(xc_interface *xch, in
/* If no explicit control parameters given, use defaults */
max_iters = max_iters ? : DEF_MAX_ITERS;
max_factor = max_factor ? : DEF_MAX_FACTOR;
+ min_remaining = min_remaining ? : DEF_MIN_REMAINING;
if ( !get_platform_info(xch, dom,
&ctx->max_mfn, &ctx->hvirt_start, &ctx->pt_levels, &dinfo->guest_width) )
@@ -1563,10 +1567,22 @@ int xc_domain_save(xc_interface *xch, in
if ( live )
{
+ int min_reached = sent_this_iter + skip_this_iter < min_remaining;
if ( (iter >= max_iters) ||
- (sent_this_iter+skip_this_iter < 50) ||
+ min_reached ||
(total_sent > dinfo->p2m_size*max_factor) )
{
+ if ( !min_reached && abort_if_busy )
+ {
+ errnoval = EBUSY;
+ DPRINTF("Live migration aborted, as requested. (guest too busy?)");
+ DPRINTF(" total_sent %lu iter %d, max_iters %u max_factor %u",
+ total_sent, iter, max_iters, max_factor);
+ print_stats(xch, dom, sent_this_iter, &time_stats, &shadow_stats, 1);
+ rc = 1;
+ goto out;
+ }
+
DPRINTF("Start last iteration\n");
last_iter = 1;
@@ -2210,6 +2226,13 @@ exit:
return !!rc;
}
+int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
+ uint32_t max_factor, uint32_t flags,
+ struct save_callbacks* callbacks, int hvm,
+ unsigned long vm_generationid_addr)
+{
+ return xc_domain_save_suse(xch, io_fd, dom, max_iters, max_factor, flags, 0, callbacks, hvm, vm_generationid_addr);
+}
/*
* Local variables:
Index: xen-4.4.3-testing/tools/libxc/xc_nomigrate.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxc/xc_nomigrate.c
+++ xen-4.4.3-testing/tools/libxc/xc_nomigrate.c
@@ -21,6 +21,16 @@
#include
#include
+int xc_domain_save_suse(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
+ uint32_t max_factor, uint32_t flags,
+ uint32_t min_remaining,
+ struct save_callbacks* callbacks, int hvm,
+ unsigned long vm_generationid_addr)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
uint32_t max_factor, uint32_t flags,
struct save_callbacks* callbacks, int hvm,
Index: xen-4.4.3-testing/tools/libxc/xenguest.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxc/xenguest.h
+++ xen-4.4.3-testing/tools/libxc/xenguest.h
@@ -28,6 +28,7 @@
#define XCFLAGS_HVM (1 << 2)
#define XCFLAGS_STDVGA (1 << 3)
#define XCFLAGS_CHECKPOINT_COMPRESS (1 << 4)
+#define XCFLAGS_DOMSAVE_ABORT_IF_BUSY (1 << 5)
#define X86_64_B_SIZE 64
#define X86_32_B_SIZE 32
@@ -89,6 +90,12 @@ int xc_domain_save(xc_interface *xch, in
struct save_callbacks* callbacks, int hvm,
unsigned long vm_generationid_addr);
+int xc_domain_save_suse(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iters,
+ uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
+ uint32_t min_remaining,
+ struct save_callbacks* callbacks, int hvm,
+ unsigned long vm_generationid_addr);
+
/* callbacks provided by xc_domain_restore */
struct restore_callbacks {
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -777,7 +777,8 @@ static void domain_suspend_cb(libxl__egc
}
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+static int do_libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+ const libxl_domain_suspend_suse_properties *props,
const libxl_asyncop_how *ao_how)
{
AO_CREATE(ctx, domid, ao_how);
@@ -798,8 +799,14 @@ int libxl_domain_suspend(libxl_ctx *ctx,
dss->domid = domid;
dss->fd = fd;
dss->type = type;
- dss->live = flags & LIBXL_SUSPEND_LIVE;
- dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+ if (props) {
+ dss->live = props->flags & LIBXL_SUSPEND_LIVE;
+ dss->debug = props->flags & LIBXL_SUSPEND_DEBUG;
+ dss->max_iters = props->max_iters;
+ dss->max_factor = props->max_factor;
+ dss->min_remaining = props->min_remaining;
+ dss->xlflags = props->flags;
+ }
libxl__domain_suspend(egc, dss);
return AO_INPROGRESS;
@@ -808,6 +815,20 @@ int libxl_domain_suspend(libxl_ctx *ctx,
return AO_ABORT(rc);
}
+int libxl_domain_suspend_suse(libxl_ctx *ctx, uint32_t domid, int fd,
+ const libxl_domain_suspend_suse_properties *props,
+ const libxl_asyncop_how *ao_how)
+{
+ return do_libxl_domain_suspend(ctx, domid, fd, props, ao_how);
+}
+
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+ const libxl_asyncop_how *ao_how)
+{
+ libxl_domain_suspend_suse_properties props = { .flags = flags };
+ return do_libxl_domain_suspend(ctx, domid, fd, &props, ao_how);
+}
+
int libxl_domain_pause(libxl_ctx *ctx, uint32_t domid)
{
int ret;
Index: xen-4.4.3-testing/tools/libxl/libxl.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.h
+++ xen-4.4.3-testing/tools/libxl/libxl.h
@@ -702,8 +702,23 @@ int libxl_domain_suspend(libxl_ctx *ctx,
int flags, /* LIBXL_SUSPEND_* */
const libxl_asyncop_how *ao_how)
LIBXL_EXTERNAL_CALLERS_ONLY;
+
+typedef struct {
+ int flags; /* LIBXL_SUSPEND_* */
+ int max_iters;
+ int max_factor;
+ int min_remaining;
+} libxl_domain_suspend_suse_properties;
+
+#define LIBXL_HAVE_DOMAIN_SUSPEND_SUSE
+int libxl_domain_suspend_suse(libxl_ctx *ctx, uint32_t domid, int fd,
+ const libxl_domain_suspend_suse_properties *props, /* optional */
+ const libxl_asyncop_how *ao_how)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
+
#define LIBXL_SUSPEND_DEBUG 1
#define LIBXL_SUSPEND_LIVE 2
+#define LIBXL_SUSPEND_ABORT_IF_BUSY 4
/* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
* If this parameter is true, use co-operative resume. The guest
Index: xen-4.4.3-testing/tools/libxl/libxl_dom.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_dom.c
+++ xen-4.4.3-testing/tools/libxl/libxl_dom.c
@@ -1345,6 +1345,7 @@ void libxl__domain_suspend(libxl__egc *e
dss->xcflags = (live ? XCFLAGS_LIVE : 0)
| (debug ? XCFLAGS_DEBUG : 0)
+ | (dss->xlflags & LIBXL_SUSPEND_ABORT_IF_BUSY ? XCFLAGS_DOMSAVE_ABORT_IF_BUSY : 0)
| (dss->hvm ? XCFLAGS_HVM : 0);
dss->suspend_eventchn = -1;
Index: xen-4.4.3-testing/tools/libxl/libxl_internal.h
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_internal.h
+++ xen-4.4.3-testing/tools/libxl/libxl_internal.h
@@ -2332,6 +2332,10 @@ struct libxl__domain_suspend_state {
xc_evtchn *xce; /* event channel handle */
int suspend_eventchn;
int hvm;
+ int max_iters;
+ int max_factor;
+ int min_remaining;
+ int xlflags;
int xcflags;
int guest_responded;
const char *dm_savefile;
Index: xen-4.4.3-testing/tools/libxl/libxl_save_callout.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_save_callout.c
+++ xen-4.4.3-testing/tools/libxl/libxl_save_callout.c
@@ -108,7 +108,9 @@ void libxl__xc_domain_save(libxl__egc *e
}
const unsigned long argnums[] = {
- dss->domid, 0, 0, dss->xcflags, dss->hvm, vm_generationid_addr,
+ dss->domid,
+ dss->max_iters, dss->max_factor, dss->min_remaining,
+ dss->xcflags, dss->hvm, vm_generationid_addr,
toolstack_data_fd, toolstack_data_len,
cbflags,
};
Index: xen-4.4.3-testing/tools/libxl/libxl_save_helper.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_save_helper.c
+++ xen-4.4.3-testing/tools/libxl/libxl_save_helper.c
@@ -221,6 +221,7 @@ int main(int argc, char **argv)
uint32_t dom = strtoul(NEXTARG,0,10);
uint32_t max_iters = strtoul(NEXTARG,0,10);
uint32_t max_factor = strtoul(NEXTARG,0,10);
+ uint32_t min_remaining = strtoul(NEXTARG,0,10);
uint32_t flags = strtoul(NEXTARG,0,10);
int hvm = atoi(NEXTARG);
unsigned long genidad = strtoul(NEXTARG,0,10);
@@ -235,7 +236,8 @@ int main(int argc, char **argv)
helper_setcallbacks_save(&helper_save_callbacks, cbflags);
startup("save");
- r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags,
+ r = xc_domain_save_suse(xch, io_fd, dom, max_iters, max_factor, flags,
+ min_remaining,
&helper_save_callbacks, hvm, genidad);
complete(r);
Index: xen-4.4.3-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.4.3-testing/tools/libxl/xl_cmdimpl.c
@@ -3660,6 +3660,8 @@ static void migrate_do_preamble(int send
}
static void migrate_domain(uint32_t domid, const char *rune, int debug,
+ int max_iters, int max_factor,
+ int min_remaining, int abort_if_busy,
const char *override_config_file)
{
pid_t child = -1;
@@ -3668,7 +3670,13 @@ static void migrate_domain(uint32_t domi
char *away_domname;
char rc_buf;
uint8_t *config_data;
- int config_len, flags = LIBXL_SUSPEND_LIVE;
+ int config_len;
+ libxl_domain_suspend_suse_properties props = {
+ .flags = LIBXL_SUSPEND_LIVE,
+ .max_iters = max_iters,
+ .max_factor = max_factor,
+ .min_remaining = min_remaining,
+ };
save_domain_core_begin(domid, override_config_file,
&config_data, &config_len);
@@ -3687,10 +3695,13 @@ static void migrate_domain(uint32_t domi
xtl_stdiostream_adjust_flags(logger, XTL_STDIOSTREAM_HIDE_PROGRESS, 0);
if (debug)
- flags |= LIBXL_SUSPEND_DEBUG;
- rc = libxl_domain_suspend(ctx, domid, send_fd, flags, NULL);
+ props.flags |= LIBXL_SUSPEND_DEBUG;
+ if (abort_if_busy)
+ props.flags |= LIBXL_SUSPEND_ABORT_IF_BUSY;
+
+ rc = libxl_domain_suspend_suse(ctx, domid, send_fd, &props, NULL);
if (rc) {
- fprintf(stderr, "migration sender: libxl_domain_suspend failed"
+ fprintf(stderr, "migration sender: libxl_domain_suspend_suse failed"
" (rc=%d)\n", rc);
if (rc == ERROR_GUEST_TIMEDOUT)
goto failed_suspend;
@@ -4077,13 +4088,18 @@ int main_migrate(int argc, char **argv)
char *rune = NULL;
char *host;
int opt, daemonize = 1, monitor = 1, debug = 0;
+ int max_iters = 0, max_factor = 0, min_remaining = 0, abort_if_busy = 0;
static struct option opts[] = {
{"debug", 0, 0, 0x100},
+ {"max_iters", 1, 0, 0x101},
+ {"max_factor", 1, 0, 0x102},
+ {"min_remaining", 1, 0, 0x103},
+ {"abort_if_busy", 0, 0, 0x104},
COMMON_LONG_OPTS,
{0, 0, 0, 0}
};
- SWITCH_FOREACH_OPT(opt, "FC:s:e", opts, "migrate", 2) {
+ SWITCH_FOREACH_OPT(opt, "FC:s:eM:m:A", opts, "migrate", 2) {
case 'C':
config_filename = optarg;
break;
@@ -4100,6 +4116,18 @@ int main_migrate(int argc, char **argv)
case 0x100:
debug = 1;
break;
+ case 0x101:
+ max_iters = atoi(optarg);
+ break;
+ case 0x102:
+ max_factor = atoi(optarg);
+ break;
+ case 0x103:
+ min_remaining = atoi(optarg);
+ break;
+ case 0x104:
+ abort_if_busy = 1;
+ break;
}
domid = find_domain(argv[optind]);
@@ -4115,7 +4143,8 @@ int main_migrate(int argc, char **argv)
return 1;
}
- migrate_domain(domid, rune, debug, config_filename);
+ migrate_domain(domid, rune, debug, max_iters, max_factor, min_remaining,
+ abort_if_busy, config_filename);
return 0;
}
#endif
Index: xen-4.4.3-testing/tools/libxl/xl_cmdtable.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/xl_cmdtable.c
+++ xen-4.4.3-testing/tools/libxl/xl_cmdtable.c
@@ -150,14 +150,21 @@ struct cmd_spec cmd_table[] = {
&main_migrate, 0, 1,
"Migrate a domain to another host",
"[options] <Domain> <host>",
- "-h Print this help.\n"
- "-C <config> Send <config> instead of config file from creation.\n"
- "-s <sshcommand> Use <sshcommand> instead of ssh. String will be passed\n"
- " to sh. If empty, run <host> instead of ssh <host> xl\n"
- " migrate-receive [-d -e]\n"
- "-e Do not wait in the background (on <host>) for the death\n"
- " of the domain.\n"
- "--debug Print huge (!) amount of debug during the migration process."
+ "-h Print this help.\n"
+ "-C <config> Send <config> instead of config file from creation.\n"
+ "-s <sshcommand> Use <sshcommand> instead of ssh. String will be passed\n"
+ " to sh. If empty, run <host> instead of ssh <host> xl\n"
+ " migrate-receive [-d -e]\n"
+ "-e Do not wait in the background (on <host>) for the death\n"
+ " of the domain.\n"
+ "--debug Print huge (!) amount of debug during the migration process.\n"
+ "\n"
+ "SUSE Linux specific options:\n"
+ "--max_iters <number> Number of iterations before final suspend (default: 30)\n"
+ "--max_factor <factor> Max amount of memory to transfer before final suspend (default: 3*RAM).\n"
+ "--min_remaining <pages> Number of remaining dirty pages before final suspend (default: 50).\n"
+ "--abort_if_busy Abort migration instead of doing final suspend, if number\n"
+ " of iterations or amount of transfered memory is exceeded."
},
{ "restore",
&main_restore, 0, 1,
++++++ local_attach_support_for_phy.patch ++++++
commit 3bcf91cbbd9a18db9ae7d594ffde7979774ed512
Author: Roger Pau Monne
Date: Wed Feb 12 11:15:17 2014 +0100
libxl: local attach support for PHY backends using scripts
Allow disks using the PHY backend to locally attach if using a script.
Signed-off-by: Roger Pau MonnÃ
Suggested-by: Ian Campbell
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -2647,6 +2647,16 @@ void libxl__device_disk_local_initiate_a
switch (disk->backend) {
case LIBXL_DISK_BACKEND_PHY:
+ if (disk->script != NULL) {
+ LOG(DEBUG, "trying to locally attach PHY device %s with script %s",
+ disk->pdev_path, disk->script);
+ libxl__prepare_ao_device(ao, &dls->aodev);
+ dls->aodev.callback = local_device_attach_cb;
+ device_disk_add(egc, LIBXL_TOOLSTACK_DOMID, disk,
+ &dls->aodev, libxl__alloc_vdev,
+ (void *) blkdev_start);
+ return;
+ }
LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "locally attaching PHY disk %s",
disk->pdev_path);
dev = disk->pdev_path;
@@ -2726,7 +2736,7 @@ static void local_device_attach_cb(libxl
}
dev = GCSPRINTF("/dev/%s", disk->vdev);
- LOG(DEBUG, "locally attaching qdisk %s", dev);
+ LOG(DEBUG, "locally attached disk %s", dev);
rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &device);
if (rc < 0)
@@ -2766,6 +2776,7 @@ void libxl__device_disk_local_initiate_d
if (!dls->diskpath) goto out;
switch (disk->backend) {
+ case LIBXL_DISK_BACKEND_PHY:
case LIBXL_DISK_BACKEND_QDISK:
if (disk->vdev != NULL) {
GCNEW(device);
@@ -2783,7 +2794,6 @@ void libxl__device_disk_local_initiate_d
/* disk->vdev == NULL; fall through */
default:
/*
- * Nothing to do for PHYSTYPE_PHY.
* For other device types assume that the blktap2 process is
* needed by the soon to be started domain and do nothing.
*/
++++++ log-guest-console.patch ++++++
Add code to support logging xen-domU console, as what xenconsoled does. Log info
will be saved in /var/log/xen/console/guest-domUname.log.
Signed-off-by: Chunyan Liu
---
hw/xen_console.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_console.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_console.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_console.c
@@ -38,6 +38,8 @@
#include "qemu-char.h"
#include "xen_backend.h"
+static int log_guest = 0;
+
struct buffer {
uint8_t *data;
size_t consumed;
@@ -54,8 +56,24 @@ struct XenConsole {
void *sring;
CharDriverState *chr;
int backlog;
+ int log_fd;
};
+static int write_all(int fd, const char* buf, size_t len)
+{
+ while (len) {
+ ssize_t ret = write(fd, buf, len);
+ if (ret == -1 && errno == EINTR)
+ continue;
+ if (ret < 0)
+ return -1;
+ len -= ret;
+ buf += ret;
+ }
+
+ return 0;
+}
+
static void buffer_append(struct XenConsole *con)
{
struct buffer *buffer = &con->buffer;
@@ -83,6 +101,15 @@ static void buffer_append(struct XenCons
intf->out_cons = cons;
xen_be_send_notify(&con->xendev);
+ if (con->log_fd != -1) {
+ int logret;
+ logret = write_all(con->log_fd, buffer->data + buffer->size - size, size);
+ if (logret < 0) {
+ xen_be_printf(&con->xendev, 1, "Write to log failed on domain %d: %d (%s)\n",
+ con->xendev.dom, errno, strerror(errno));
+ }
+ }
+
if (buffer->max_capacity &&
buffer->size > buffer->max_capacity) {
/* Discard the middle of the data. */
@@ -176,6 +203,37 @@ static void xencons_send(struct XenConso
}
}
+static int create_domain_log(struct XenConsole *con)
+{
+ char *logfile;
+ char *path, *domname;
+ int fd;
+ const char *logdir = "/var/log/xen/console";
+
+ path = xs_get_domain_path(xenstore, con->xendev.dom);
+ domname = xenstore_read_str(path, "name");
+ free(path);
+ if (!domname)
+ return -1;
+
+ if (mkdir(logdir, 0755) && errno != EEXIST)
+ {
+ xen_be_printf(&con->xendev, 1, "Directory %s does not exist and fail to create it!", logdir);
+ return -1;
+ }
+
+ if (asprintf(&logfile, "%s/guest-%s.log", logdir, domname) < 0)
+ return -1;
+ qemu_free(domname);
+
+ fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644);
+ free(logfile);
+ if (fd == -1)
+ xen_be_printf(&con->xendev, 1, "Failed to open log %s: %d (%s)", logfile, errno, strerror(errno));
+
+ return fd;
+}
+
/* -------------------------------------------------------------------- */
static int con_init(struct XenDevice *xendev)
@@ -183,6 +241,7 @@ static int con_init(struct XenDevice *xe
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
char *type, *dom, label[32];
const char *output;
+ char *logenv = NULL;
/* setup */
dom = xs_get_domain_path(xenstore, con->xendev.dom);
@@ -209,6 +268,10 @@ static int con_init(struct XenDevice *xe
con->chr = qemu_chr_open(label, output, NULL);
xenstore_store_pv_console_info(con->xendev.dev, con->chr, output);
+ logenv = getenv("XENCONSOLED_TRACE");
+ if (logenv != NULL && strlen(logenv) == strlen("guest") && !strcmp(logenv, "guest")) {
+ log_guest = 1;
+ }
return 0;
}
@@ -246,6 +309,9 @@ static int con_initialise(struct XenDevi
con->xendev.remote_port,
con->xendev.local_port,
con->buffer.max_capacity);
+ con->log_fd = -1;
+ if (log_guest)
+ con->log_fd = create_domain_log(con);
return 0;
}
@@ -266,6 +332,12 @@ static void con_disconnect(struct XenDev
xc_gnttab_munmap(xendev->gnttabdev, con->sring, 1);
con->sring = NULL;
}
+
+ if (con->log_fd != -1) {
+ close(con->log_fd);
+ con->log_fd = -1;
+ }
+
}
static void con_event(struct XenDevice *xendev)
++++++ logrotate.conf ++++++
compress
missingok
/var/log/xen/xend*.log {
rotate 5
size 1M
notifempty
copytruncate
}
/var/log/xen/domain-builder-ng.log /var/log/xen/xen-hotplug.log {
rotate 2
size 100k
notifempty
copytruncate
}
/var/log/xen/qemu-dm.*.log {
rotate 0
monthly
}
++++++ magic_ioport_compat.patch ++++++
Make our PV drivers work with older hosts that do not recognize the new PV driver protocol.
Signed-off-by: K. Y. Srinivasan
Index: xen-4.4.0-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
===================================================================
--- xen-4.4.0-testing.orig/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
+++ xen-4.4.0-testing/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
@@ -337,7 +337,10 @@ static int check_platform_magic(struct d
if (magic != XEN_IOPORT_MAGIC_VAL) {
err = "unrecognised magic value";
- goto no_dev;
+ /*
+ * Older backend; just return 0 to be compatible.
+ */
+ return 0;
}
protocol = inb(XEN_IOPORT_PROTOVER);
++++++ network-nat-open-SuSEfirewall2-FORWARD.patch ++++++
Open SuSEfirewall2 FORWARD rule when use xen nat
Index: xen-4.2.0-testing/tools/hotplug/Linux/network-nat
===================================================================
--- xen-4.2.0-testing.orig/tools/hotplug/Linux/network-nat
+++ xen-4.2.0-testing/tools/hotplug/Linux/network-nat
@@ -83,6 +83,7 @@ function dhcp_stop()
op_start() {
echo 1 >/proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o ${netdev} -j MASQUERADE
+ iptables -P FORWARD ACCEPT
[ "$dhcp" != 'no' ] && dhcp_start
}
@@ -90,6 +91,7 @@ op_start() {
op_stop() {
[ "$dhcp" != 'no' ] && dhcp_stop
iptables -t nat -D POSTROUTING -o ${netdev} -j MASQUERADE
+ iptables -P FORWARD DROP
}
++++++ pvdrv_emulation_control.patch ++++++
---
tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
@@ -370,6 +370,19 @@ static void suse_platform_ioport_write(v
net_tap_shutdown_all();
fprintf(logfile, "Done.\n");
break;
+ case 8:
+ if (val ==1 ) {
+ fprintf(logfile, "Disconnect IDE hard disk...\n");
+ ide_unplug_harddisks();
+ fprintf(logfile, "Done.\n");
+ } else if (val == 2) {
+ fprintf(logfile, "Disconnect netifs...\n");
+ pci_unplug_netifs();
+ fprintf(logfile, "Shutdown taps...\n");
+ net_tap_shutdown_all();
+ fprintf(logfile, "Done.\n");
+ }
+ break;
default:
fprintf(logfile, "Write %x to bad port %x (base %x) on evtchn device.\n",
val, addr, ioport_base);
++++++ pygrub-boot-legacy-sles.patch ++++++
Index: xen-4.4.2-testing/tools/pygrub/src/pygrub
===================================================================
--- xen-4.4.2-testing.orig/tools/pygrub/src/pygrub
+++ xen-4.4.2-testing/tools/pygrub/src/pygrub
@@ -454,7 +454,7 @@ class Grub:
self.cf.filename = f
break
if self.__dict__.get('cf', None) is None:
- raise RuntimeError, "couldn't find bootloader config file in the image provided."
+ return
f = fs.open_file(self.cf.filename)
# limit read size to avoid pathological cases
buf = f.read(FS_READ_MAX)
@@ -626,6 +626,20 @@ def run_grub(file, entry, fs, cfg_args):
g = Grub(file, fs)
+ # If missing config or grub has no menu entries to select, look for
+ # vmlinuz-xen and initrd-xen in /boot
+ if g.__dict__.get('cf', None) is None or len(g.cf.images) == 0 or re.search(r"xen(-pae)?\.gz",g.cf.images[0].kernel[1]):
+ if not list_entries:
+ chosencfg = { "kernel": None, "ramdisk": None, "args": "" }
+ chosencfg = sniff_xen_kernel(fs, incfg)
+ if chosencfg["kernel"] and chosencfg["ramdisk"]:
+ chosencfg["args"] = cfg_args
+ return chosencfg
+ if g.__dict__.get('cf', None) is None:
+ raise RuntimeError, "couldn't find bootloader config file in the image provided."
+ else:
+ return
+
if list_entries:
for i in range(len(g.cf.images)):
img = g.cf.images[i]
@@ -721,6 +735,19 @@ def sniff_netware(fs, cfg):
return cfg
+def sniff_xen_kernel(fs, cfg):
+ if not cfg["kernel"]:
+ if fs.file_exists('/boot/vmlinuz-xen'):
+ cfg["kernel"] = '/boot/vmlinuz-xen'
+ elif fs.file_exists('/boot/vmlinuz-xenpae'):
+ cfg["kernel"] = '/boot/vmlinuz-xenpae'
+ if cfg["kernel"] and not cfg["ramdisk"]:
+ if fs.file_exists('/boot/initrd-xen'):
+ cfg["ramdisk"] = '/boot/initrd-xen'
+ elif fs.file_exists('/boot/initrd-xenpae'):
+ cfg["ramdisk"] = '/boot/initrd-xenpae'
+ return cfg
+
def format_sxp(kernel, ramdisk, args):
s = "linux (kernel %s)" % kernel
if ramdisk:
@@ -801,7 +828,7 @@ if __name__ == "__main__":
debug = False
not_really = False
output_format = "sxp"
- output_directory = "/var/run/xend/boot"
+ output_directory = "/var/run/xen"
# what was passed in
incfg = { "kernel": None, "ramdisk": None, "args": "" }
++++++ pygrub-netware-xnloader.patch ++++++
Index: xen-4.4.2-testing/tools/pygrub/src/pygrub
===================================================================
--- xen-4.4.2-testing.orig/tools/pygrub/src/pygrub
+++ xen-4.4.2-testing/tools/pygrub/src/pygrub
@@ -26,6 +26,7 @@ import fsimage
import grub.GrubConf
import grub.LiloConf
import grub.ExtLinuxConf
+import xnloader
PYGRUB_VER = 0.6
FS_READ_MAX = 1024 * 1024
@@ -763,6 +764,8 @@ if __name__ == "__main__":
if len(data) == 0:
os.close(tfd)
del datafile
+ if file_to_read == "/nwserver/xnloader.sys":
+ xnloader.patch_netware_loader(ret)
return ret
try:
os.write(tfd, data)
++++++ qemu-dm-segfault.patch ++++++
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/ide.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/ide.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/ide.c
@@ -935,8 +935,9 @@ static inline void ide_dma_submit_check(
static inline void ide_set_irq(IDEState *s)
{
- BMDMAState *bm = s->bmdma;
- if (!s->bs) return; /* ouch! (see ide_flush_cb) */
+ BMDMAState *bm;
+ if (!s || !s->bs) return; /* ouch! (see ide_flush_cb) */
+ bm = s->bmdma;
if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
if (bm) {
bm->status |= BM_STATUS_INT;
@@ -1224,14 +1225,14 @@ static void ide_read_dma_cb(void *opaque
int n;
int64_t sector_num;
+ if (!s || !s->bs) return; /* ouch! (see ide_flush_cb) */
+
if (ret < 0) {
dma_buf_commit(s, 1);
ide_dma_error(s);
return;
}
- if (!s->bs) return; /* ouch! (see ide_flush_cb) */
-
n = s->io_buffer_size >> 9;
sector_num = ide_get_sector(s);
if (n > 0) {
@@ -1335,6 +1336,8 @@ static void ide_write_flush_cb(void *opa
BMDMAState *bm = opaque;
IDEState *s = bm->ide_if;
+ if (!s) return; /* yikes */
+
if (ret != 0) {
ide_dma_error(s);
return;
@@ -1366,13 +1369,13 @@ static void ide_write_dma_cb(void *opaqu
int n;
int64_t sector_num;
+ if (!s || !s->bs) return; /* ouch! (see ide_flush_cb) */
+
if (ret < 0) {
if (ide_handle_write_error(s, -ret, BM_STATUS_DMA_RETRY))
return;
}
- if (!s->bs) return; /* ouch! (see ide_flush_cb) */
-
n = s->io_buffer_size >> 9;
sector_num = ide_get_sector(s);
if (n > 0) {
@@ -1429,7 +1432,7 @@ static void ide_flush_cb(void *opaque, i
{
IDEState *s = opaque;
- if (!s->bs) return; /* ouch! (see below) */
+ if (!s || !s->bs) return; /* ouch! (see below) */
if (ret) {
/* We are completely doomed. The IDE spec does not permit us
@@ -1686,7 +1689,7 @@ static void ide_atapi_cmd_read_dma_cb(vo
IDEState *s = bm->ide_if;
int data_offset, n;
- if (!s->bs) return; /* ouch! (see ide_flush_cb) */
+ if (!s || !s->bs) return; /* ouch! (see ide_flush_cb) */
if (ret < 0) {
ide_atapi_io_error(s, ret);
@@ -2372,7 +2375,7 @@ static void cdrom_change_cb(void *opaque
IDEState *s = opaque;
uint64_t nb_sectors;
- if (!s->bs) return; /* ouch! (see ide_flush_cb) */
+ if (!s || !s->bs) return; /* ouch! (see ide_flush_cb) */
bdrv_get_geometry(s->bs, &nb_sectors);
s->nb_sectors = nb_sectors;
++++++ qemu-ifup-set-mtu.patch ++++++
Index: xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
===================================================================
--- xen-4.2.3-testing.orig/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
+++ xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
@@ -20,4 +20,11 @@ then
fi
ifconfig $1 0.0.0.0 up
+
+mtu="`ip link show $bridge | awk '/mtu/ { print $5 }'`"
+if [ -n "$mtu" ] && [ "$mtu" -gt 0 ]
+then
+ ip link set $1 mtu $mtu || :
+fi
+
brctl addif $bridge $1 || true
++++++ qemu-security-etch1.patch ++++++
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ne2000.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/ne2000.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ne2000.c
@@ -218,7 +218,7 @@ static int ne2000_can_receive(void *opaq
NE2000State *s = opaque;
if (s->cmd & E8390_STOP)
- return 1;
+ return 0;
return !ne2000_buffer_full(s);
}
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pc.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c
@@ -413,7 +413,8 @@ static void bochs_bios_write(void *opaqu
case 0x400:
case 0x401:
fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
- exit(1);
+ /* according to documentation, these can be safely ignored */
+ break;
case 0x402:
case 0x403:
#ifdef DEBUG_BIOS
@@ -436,8 +437,9 @@ static void bochs_bios_write(void *opaqu
/* LGPL'ed VGA BIOS messages */
case 0x501:
case 0x502:
+ /* according to documentation, these can be safely ignored */
fprintf(stderr, "VGA BIOS panic, line %d\n", val);
- exit(1);
+ break;
case 0x500:
case 0x503:
#ifdef DEBUG_BIOS
++++++ qemu-support-xen-hvm-direct-kernel-boot.patch ++++++
From dd708897cc5b21bc374cd44b6d58c1e74b04bd6e Mon Sep 17 00:00:00 2001
From: Chunyan Liu
Date: Wed, 28 May 2014 14:31:35 +0800
Subject: [PATCH 2/2] qemu: support xen hvm direct kernel boot
qemu side patch to support xen HVM direct kernel boot:
if -kernel exists, calls xen_load_linux(), which will read kernel/initrd
and add a linuxboot.bin or multiboot.bin option rom. The
linuxboot.bin/multiboot.bin will load kernel/initrd and jump to execute
kernel directly. It's working when xen uses seabios.
Signed-off-by: Chunyan Liu
Index: xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/i386/pc.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-dir-remote/hw/i386/pc.c
+++ xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/i386/pc.c
@@ -1105,6 +1105,35 @@ void pc_acpi_init(const char *default_ds
}
}
+FWCfgState *xen_load_linux(const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ ram_addr_t below_4g_mem_size,
+ PcGuestInfo *guest_info)
+{
+ int i;
+ FWCfgState *fw_cfg;
+
+ assert(kernel_filename != NULL);
+
+ fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
+ rom_set_fw(fw_cfg);
+
+ load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
+ for (i = 0; i < nb_option_roms; i++) {
+ /* For xen, we only want to add the linuxboot.bin/multiboot.bin option rom.
+ * But in option_rom, there is still kvmvapic.bin. We don't want to add it.
+ */
+ if (strcmp(option_rom[i].name, "linuxboot.bin") &&
+ strcmp(option_rom[i].name, "multiboot.bin")) {
+ continue;
+ }
+ rom_add_option(option_rom[i].name, option_rom[i].bootindex);
+ }
+ guest_info->fw_cfg = fw_cfg;
+ return fw_cfg;
+}
+
FWCfgState *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
Index: xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/i386/pc_piix.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-dir-remote/hw/i386/pc_piix.c
+++ xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/i386/pc_piix.c
@@ -135,6 +135,13 @@ static void pc_init1(MemoryRegion *syste
kernel_filename, kernel_cmdline, initrd_filename,
below_4g_mem_size, above_4g_mem_size,
rom_memory, &ram_memory, guest_info);
+ } else if (kernel_filename != NULL) {
+ /* For xen HVM direct kernel boot, load linux here */
+ fw_cfg = xen_load_linux(kernel_filename,
+ kernel_cmdline,
+ initrd_filename,
+ below_4g_mem_size,
+ guest_info);
}
gsi_state = g_malloc0(sizeof(*gsi_state));
Index: xen-4.4.0-testing/tools/qemu-xen-dir-remote/include/hw/i386/pc.h
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-dir-remote/include/hw/i386/pc.h
+++ xen-4.4.0-testing/tools/qemu-xen-dir-remote/include/hw/i386/pc.h
@@ -120,6 +120,11 @@ static inline uint64_t pci_host_get_hole
void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,
uint64_t pci_hole64_size);
+FWCfgState *xen_load_linux(const char *kernel_filename,
+ const char *kernel_cmdline,
+ const char *initrd_filename,
+ ram_addr_t below_4g_mem_size,
+ PcGuestInfo *guest_info);
FWCfgState *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
++++++ qemu-xen-enable-spice-support.patch ++++++
Index: xen-4.4.1-testing/tools/Makefile
===================================================================
--- xen-4.4.1-testing.orig/tools/Makefile
+++ xen-4.4.1-testing/tools/Makefile
@@ -201,6 +201,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-fi
--datadir=$(SHAREDIR)/qemu-xen \
--localstatedir=/var \
--disable-kvm \
+ $(QEMU_XEN_ENABLE_SPICE) \
--disable-docs \
--disable-guest-agent \
--python=$(PYTHON) \
++++++ qemu-xen-upstream-blkif-discard.patch ++++++
References: FATE#316071
Subject: qemu-upstream: add discard support for xen_disk
Git-commit: f31352041bdde436c3f6d07e1525a42e48dec215
Implement discard support for xen_disk. It makes use of the existing
discard code in qemu.
The discard support is enabled unconditionally. The tool stack may provide a
property "discard-enable" in the backend node to optionally disable discard
support. This is helpful in case the backing file was intentionally created
non-sparse to avoid fragmentation.
v2:
rename xenstore property from discard_enable to discard-enable
move discard_req to case BLKIF_OP_DISCARD
Signed-off-by: Olaf Hering
---
tools/qemu-xen-dir-remote/hw/block/xen_blkif.h | 12 ++++++++++
tools/qemu-xen-dir-remote/hw/block/xen_disk.c | 30 +++++++++++++++++++++++++
2 files changed, 42 insertions(+)
Index: xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/block/xen_blkif.h
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-dir-remote/hw/block/xen_blkif.h
+++ xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/block/xen_blkif.h
@@ -79,6 +79,12 @@ static inline void blkif_get_x86_32_req(
dst->handle = src->handle;
dst->id = src->id;
dst->sector_number = src->sector_number;
+ if (src->operation == BLKIF_OP_DISCARD) {
+ struct blkif_request_discard *s = (void *)src;
+ struct blkif_request_discard *d = (void *)dst;
+ d->nr_sectors = s->nr_sectors;
+ return;
+ }
/* prevent the compiler from optimizing the code and using src->nr_segments instead */
barrier();
if (n > dst->nr_segments)
@@ -96,6 +102,12 @@ static inline void blkif_get_x86_64_req(
dst->handle = src->handle;
dst->id = src->id;
dst->sector_number = src->sector_number;
+ if (src->operation == BLKIF_OP_DISCARD) {
+ struct blkif_request_discard *s = (void *)src;
+ struct blkif_request_discard *d = (void *)dst;
+ d->nr_sectors = s->nr_sectors;
+ return;
+ }
/* prevent the compiler from optimizing the code and using src->nr_segments instead */
barrier();
if (n > dst->nr_segments)
Index: xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/block/xen_disk.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-dir-remote/hw/block/xen_disk.c
+++ xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/block/xen_disk.c
@@ -121,6 +121,7 @@ struct XenBlkDev {
int requests_finished;
/* Persistent grants extension */
+ gboolean feature_discard;
gboolean feature_persistent;
GTree *persistent_gnts;
GSList *persistent_regions;
@@ -278,6 +279,8 @@ static int ioreq_parse(struct ioreq *ior
case BLKIF_OP_WRITE:
ioreq->prot = PROT_READ; /* from memory */
break;
+ case BLKIF_OP_DISCARD:
+ return 0;
default:
xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
ioreq->req.operation);
@@ -563,6 +566,16 @@ static int ioreq_runio_qemu_aio(struct i
&ioreq->v, ioreq->v.size / BLOCK_SIZE,
qemu_aio_complete, ioreq);
break;
+ case BLKIF_OP_DISCARD:
+ {
+ struct blkif_request_discard *discard_req = (void *)&ioreq->req;
+ bdrv_acct_start(blkdev->bs, &ioreq->acct, discard_req->nr_sectors * BLOCK_SIZE, BDRV_ACCT_WRITE);
+ ioreq->aio_inflight++;
+ bdrv_aio_discard(blkdev->bs,
+ discard_req->sector_number, discard_req->nr_sectors,
+ qemu_aio_complete, ioreq);
+ break;
+ }
default:
/* unknown operation (shouldn't happen -- parse catches this) */
goto err;
@@ -741,6 +754,19 @@ static void blk_alloc(struct XenDevice *
}
}
+static void blk_parse_discard(struct XenBlkDev *blkdev)
+{
+ int enable;
+
+ blkdev->feature_discard = true;
+
+ if (xenstore_read_be_int(&blkdev->xendev, "discard-enable", &enable) == 0)
+ blkdev->feature_discard = !!enable;
+
+ if (blkdev->feature_discard)
+ xenstore_write_be_int(&blkdev->xendev, "feature-discard", 1);
+}
+
static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
@@ -808,6 +834,8 @@ static int blk_init(struct XenDevice *xe
xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
xenstore_write_be_int(&blkdev->xendev, "info", info);
+ blk_parse_discard(blkdev);
+
g_free(directiosafe);
return 0;
@@ -843,6 +871,8 @@ static int blk_connect(struct XenDevice
qflags |= BDRV_O_RDWR;
readonly = false;
}
+ if (blkdev->feature_discard)
+ qflags |= BDRV_O_UNMAP;
/* init qemu block driver */
index = (blkdev->xendev.dev - 202 * 256) / 16;
++++++ qemu-xen-upstream-megasas-buildtime.patch ++++++
Causes rebuilds.
Says rpmlint.
---
tools/qemu-xen-dir-remote/hw/scsi/megasas.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-dir-remote/hw/scsi/megasas.c
+++ xen-4.4.0-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c
@@ -712,8 +712,8 @@ static int megasas_ctrl_get_info(Megasas
snprintf(info.package_version, 0x60, "%s-QEMU", QEMU_VERSION);
memcpy(info.image_component[0].name, "APP", 3);
memcpy(info.image_component[0].version, MEGASAS_VERSION "-QEMU", 9);
- memcpy(info.image_component[0].build_date, __DATE__, 11);
- memcpy(info.image_component[0].build_time, __TIME__, 8);
+ memcpy(info.image_component[0].build_date, "Apr 1 2014", 11);
+ memcpy(info.image_component[0].build_time, "12:34:56", 8);
info.image_component_count = 1;
if (pci_dev->has_rom) {
uint8_t biosver[32];
++++++ qemu-xen-upstream-qdisk-cache-unsafe.patch ++++++
https://bugzilla.novell.com/show_bug.cgi?id=879425
---
tools/qemu-xen-dir-remote/hw/block/xen_disk.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
Index: xen-4.4.2-testing/tools/qemu-xen-dir-remote/hw/block/xen_disk.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-dir-remote/hw/block/xen_disk.c
+++ xen-4.4.2-testing/tools/qemu-xen-dir-remote/hw/block/xen_disk.c
@@ -120,6 +120,7 @@ struct XenBlkDev {
int requests_inflight;
int requests_finished;
+ gboolean cache_unsafe;
/* Persistent grants extension */
gboolean feature_discard;
gboolean feature_persistent;
@@ -767,6 +768,16 @@ static void blk_parse_discard(struct Xen
xenstore_write_be_int(&blkdev->xendev, "feature-discard", 1);
}
+static void blk_parse_cache_unsafe(struct XenBlkDev *blkdev)
+{
+ int enable;
+
+ blkdev->cache_unsafe = false;
+
+ if (xenstore_read_be_int(&blkdev->xendev, "suse-diskcache-disable-flush", &enable) == 0)
+ blkdev->cache_unsafe = !!enable;
+}
+
static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
@@ -835,6 +846,7 @@ static int blk_init(struct XenDevice *xe
xenstore_write_be_int(&blkdev->xendev, "info", info);
blk_parse_discard(blkdev);
+ blk_parse_cache_unsafe(blkdev);
g_free(directiosafe);
return 0;
@@ -874,6 +886,9 @@ static int blk_connect(struct XenDevice
if (blkdev->feature_discard)
qflags |= BDRV_O_UNMAP;
+ if (blkdev->cache_unsafe)
+ qflags |= BDRV_O_NO_FLUSH;
+
/* init qemu block driver */
index = (blkdev->xendev.dev - 202 * 256) / 16;
blkdev->dinfo = drive_get(IF_XEN, 0, index);
++++++ set-mtu-from-bridge-for-tap-interface.patch ++++++
# HG changeset patch
# User Charles Arnold
# Date 1379427987 -3600
# Node ID e6da6ffd6749237316d4440799f0a0272bbdae9c
# Parent 5597ce99ec7f2587a29f3b2dee0bde98d59bf327
tools/hotplug: set mtu from bridge for tap interface
With changeset 22885 support was added for setting the MTU in the vif-bridge
script for when a vif interface was set to 'online'. The was not done for the
'add' operation. The 'add' operation was added to the script for when tap
devices were specified (c/s 21944). With the setting of the MTU for the
'online' case was there a reason for omitting the 'add'?
This patch sets the MTU for both 'online' and 'add' in the vif-bridge script.
Signed-off-by: Charles Arnold
Acked-by: Ian Campbell
Index: xen-4.4.0-testing/tools/hotplug/Linux/vif-bridge
===================================================================
--- xen-4.4.0-testing.orig/tools/hotplug/Linux/vif-bridge
+++ xen-4.4.0-testing/tools/hotplug/Linux/vif-bridge
@@ -88,7 +88,7 @@ fi
case "$command" in
online)
setup_virtual_bridge_port "$dev"
- set_mtu $bridge $dev
+ set_mtu "$bridge" "$dev"
add_to_bridge "$bridge" "$dev"
;;
@@ -99,7 +99,7 @@ case "$command" in
add)
setup_virtual_bridge_port "$dev"
- set_mtu $bridge $dev
+ set_mtu "$bridge" "$dev"
add_to_bridge "$bridge" "$dev"
;;
esac
++++++ stdvga-cache.patch ++++++
Index: xen-4.2.0-testing/xen/arch/x86/hvm/stdvga.c
===================================================================
--- xen-4.2.0-testing.orig/xen/arch/x86/hvm/stdvga.c
+++ xen-4.2.0-testing/xen/arch/x86/hvm/stdvga.c
@@ -135,7 +135,10 @@ static int stdvga_outb(uint64_t addr, ui
/* When in standard vga mode, emulate here all writes to the vram buffer
* so we can immediately satisfy reads without waiting for qemu. */
- s->stdvga = (s->sr[7] == 0x00);
+ s->stdvga =
+ (s->sr[7] == 0x00) && /* standard vga mode */
+ (s->gr[6] == 0x05); /* misc graphics register w/ MemoryMapSelect=1
+ * 0xa0000-0xaffff (64k region), AlphaDis=1 */
if ( !prev_stdvga && s->stdvga )
{
++++++ supported_module.patch ++++++
Make our PV drivers "Novell supported modules"
Signed-off-by: K. Y. Srinivasan
Index: xen-4.2.0-testing/unmodified_drivers/linux-2.6/Module.supported
===================================================================
--- /dev/null
+++ xen-4.2.0-testing/unmodified_drivers/linux-2.6/Module.supported
@@ -0,0 +1,7 @@
+xen-vbd
+xen-platform-pci
+xen-vnif
+xenbus
+xen-balloon
+xen-scsi
+xen-usb
++++++ suspend_evtchn_lock.patch ++++++
Fix problems that suspend eventchannel lock file might be obselete for some reason
like segment fault or other abnormal exit, and once obselete lock file exists,
it might affact latter save process.
Have discussed with upstream, for some reason not accepted.
http://xen.1045712.n5.nabble.com/Re-PATCH-improve-suspend-evtchn-lock-proces...
Signed-off-by: Chunyan Liu
Index: xen-4.2.0-testing/tools/libxc/xc_suspend.c
===================================================================
--- xen-4.2.0-testing.orig/tools/libxc/xc_suspend.c
+++ xen-4.2.0-testing/tools/libxc/xc_suspend.c
@@ -16,8 +16,43 @@
#include "xc_private.h"
#include "xenguest.h"
+#include
+#ifdef __MINIOS__
+extern int kill (__pid_t __pid, int __sig);
+#endif
#define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn"
+/* cleanup obsolete suspend lock file which is unlinked for any reason,
+so that current process can get lock */
+static void clean_obsolete_lock(int domid)
+{
+ int fd, pid, n;
+ char buf[128];
+ char suspend_file[256];
+
+ snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d",
+ SUSPEND_LOCK_FILE, domid);
+ fd = open(suspend_file, O_RDWR);
+
+ if (fd < 0)
+ return;
+
+ n = read(fd, buf, 127);
+
+ close(fd);
+
+ if (n > 0)
+ {
+ sscanf(buf, "%d", &pid);
+ /* pid does not exist, this lock file is obsolete, just delete it */
+ if ( kill(pid,0) )
+ {
+ unlink(suspend_file);
+ return;
+ }
+ }
+}
+
static int lock_suspend_event(xc_interface *xch, int domid)
{
int fd, rc;
@@ -27,6 +62,7 @@ static int lock_suspend_event(xc_interfa
snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d",
SUSPEND_LOCK_FILE, domid);
+ clean_obsolete_lock(domid);
mask = umask(022);
fd = open(suspend_file, O_CREAT | O_EXCL | O_RDWR, 0666);
if (fd < 0)
@@ -41,6 +77,9 @@ static int lock_suspend_event(xc_interfa
rc = write_exact(fd, buf, strlen(buf));
close(fd);
+ if(rc)
+ unlink(suspend_file);
+
return rc;
}
@@ -127,8 +166,7 @@ int xc_suspend_evtchn_init(xc_interface
return suspend_evtchn;
cleanup:
- if (suspend_evtchn != -1)
- xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
+ xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
return -1;
}
++++++ sysconfig.pciback ++++++
## Path: System/Virtualization
## Type: string
## Default: ""
#
# Space delimited list of PCI devices to late bind to pciback
# Format: <driver>,<PCI ID>
#
#XEN_PCI_HIDE_LIST="e1000,0000:0b:00.0 e1000,0000:0b:00.1"
XEN_PCI_HIDE_LIST=""
++++++ tapdisk-ioemu-logfile.patch ++++++
From 903a145f3eace5e3ae914f0335ab6c4e33635d2f Mon Sep 17 00:00:00 2001
From: Kevin Wolf
Date: Tue, 10 Mar 2009 16:36:23 +0100
Subject: [PATCH 4/6] tapdisk-ioemu: Write messages to a logfile
Typically, tapdisk-ioemu runs as a daemon and messages to stderr are
simply lost. Write them to a logfile instead.
Signed-off-by: Kevin Wolf
---
tapdisk-ioemu.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
@@ -78,15 +78,22 @@ int main(void)
struct timeval tv;
void *old_fd_start = NULL;
- logfile = stderr;
-
+ /* Daemonize */
+ if (fork() != 0)
+ exit(0);
+
bdrv_init();
init_blktap();
- /* Daemonize */
- if (fork() != 0)
- exit(0);
-
+ logfile = fopen("/var/log/xen/tapdisk-ioemu.log", "a");
+ if (logfile) {
+ setbuf(logfile, NULL);
+ fclose(stderr);
+ stderr = logfile;
+ } else {
+ logfile = stderr;
+ }
+
/*
* Main loop: Pass events to the corrsponding handlers and check for
* completed aio operations.
++++++ tapdisk-ioemu-shutdown-fix.patch ++++++
From 9062564d79cb45029403cc998b48410e42ead924 Mon Sep 17 00:00:00 2001
From: Kevin Wolf
Date: Tue, 10 Mar 2009 16:45:44 +0100
Subject: [PATCH 6/6] tapdisk-ioemu: Fix shutdown condition
Even when opening the only image a tapdisk-ioemu instance is
responsible for fails, it can't immediately shut down. blktapctrl
still wants to communicate with tapdisk-ioemu and close the disk.
This patch changes tapdisk-ioemu to count the connections to
blktapctrl rather than the number of opened disk images.
Signed-off-by: Kevin Wolf
---
hw/xen_blktap.c | 5 ++++-
tapdisk-ioemu.c | 13 ++++++++++---
2 files changed, 14 insertions(+), 4 deletions(-)
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
@@ -65,6 +65,7 @@ int read_fd;
int write_fd;
static pid_t process;
+int connected_disks = 0;
fd_list_entry_t *fd_start = NULL;
static void handle_blktap_iomsg(void* private);
@@ -541,6 +542,7 @@ static void handle_blktap_ctrlmsg(void*
/* Allocate the disk structs */
s = state_init();
+ connected_disks++;
/*Open file*/
if (s == NULL || open_disk(s, path, msg->drivertype, msg->readonly)) {
@@ -591,7 +593,8 @@ static void handle_blktap_ctrlmsg(void*
case CTLMSG_CLOSE:
s = get_state(msg->cookie);
if (s) unmap_disk(s);
- break;
+ connected_disks--;
+ break;
case CTLMSG_PID:
memset(buf, 0x00, MSG_SIZE);
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
@@ -14,6 +14,7 @@ extern void qemu_aio_init(void);
extern void qemu_aio_poll(void);
extern void *fd_start;
+extern int connected_disks;
int domid = 0;
FILE* logfile;
@@ -76,7 +77,7 @@ int main(void)
int max_fd;
fd_set rfds;
struct timeval tv;
- void *old_fd_start = NULL;
+ int old_connected_disks = 0;
/* Daemonize */
if (fork() != 0)
@@ -128,11 +129,17 @@ int main(void)
pioh = &ioh->next;
}
+ if (old_connected_disks != connected_disks)
+ fprintf(stderr, "connected disks: %d => %d\n",
+ old_connected_disks, connected_disks);
+
/* Exit when the last image has been closed */
- if (old_fd_start != NULL && fd_start == NULL)
+ if (old_connected_disks != 0 && connected_disks == 0) {
+ fprintf(stderr, "Last image is closed, exiting.\n");
exit(0);
+ }
- old_fd_start = fd_start;
+ old_connected_disks = connected_disks;
}
return 0;
}
++++++ tigervnc-long-press.patch ++++++
Index: xen-4.4.1-testing/tools/qemu-xen-dir-remote/ui/vnc.c
===================================================================
--- xen-4.4.1-testing.orig/tools/qemu-xen-dir-remote/ui/vnc.c
+++ xen-4.4.1-testing/tools/qemu-xen-dir-remote/ui/vnc.c
@@ -1651,6 +1651,25 @@ static void do_key_event(VncState *vs, i
if (down)
vs->modifiers_state[keycode] ^= 1;
break;
+ default:
+ if (qemu_console_is_graphic(NULL)) {
+ /* record key 'down' info. Some client like tigervnc
+ * will send key down repeatedly if user pressing a
+ * a key for long time. In this case, we should add
+ * additional key up event before repeated key down,
+ * so that it can display the key multiple times.
+ */
+ if (down) {
+ if (vs->modifiers_state[keycode]) {
+ /* add a key up event */
+ do_key_event(vs, 0, keycode, sym);
+ }
+ vs->modifiers_state[keycode] = 1;
+ } else {
+ vs->modifiers_state[keycode] = 0;
+ }
+ }
+ break;
}
/* Turn off the lock state sync logic if the client support the led
++++++ tmp-initscript-modprobe.patch ++++++
Index: xen-4.3.0-testing/tools/hotplug/Linux/init.d/xencommons
===================================================================
--- xen-4.3.0-testing.orig/tools/hotplug/Linux/init.d/xencommons
+++ xen-4.3.0-testing/tools/hotplug/Linux/init.d/xencommons
@@ -57,21 +57,27 @@ do_start () {
local time=0
local timeout=30
- modprobe xen-evtchn 2>/dev/null
- modprobe xen-gntdev 2>/dev/null
- modprobe xen-gntalloc 2>/dev/null
- modprobe xen-blkback 2>/dev/null
- modprobe xen-netback 2>/dev/null
- modprobe xen-pciback 2>/dev/null
- modprobe evtchn 2>/dev/null
- modprobe gntdev 2>/dev/null
- modprobe netbk 2>/dev/null
- modprobe blkbk 2>/dev/null
- modprobe xen-scsibk 2>/dev/null
- modprobe usbbk 2>/dev/null
- modprobe pciback 2>/dev/null
- modprobe xen-acpi-processor 2>/dev/null
- modprobe blktap2 2>/dev/null || modprobe blktap 2>/dev/null
+ #modprobe xen-evtchn 2>/dev/null
+ #modprobe xen-gntdev 2>/dev/null
+ #modprobe xen-gntalloc 2>/dev/null
+ #modprobe xen-blkback 2>/dev/null
+ #modprobe xen-netback 2>/dev/null
+ #modprobe xen-pciback 2>/dev/null
+ modprobe evtchn 2>/dev/null || true
+ modprobe gntdev 2>/dev/null || true
+ modprobe gntalloc 2>/dev/null || true
+ modprobe netbk 2>/dev/null || true
+ modprobe blkbk 2>/dev/null || true
+ modprobe xen-scsibk 2>/dev/null || true
+ modprobe usbbk 2>/dev/null || true
+ modprobe pciback 2>/dev/null || true
+ modprobe xen-acpi-processor 2>/dev/null || true
+ modprobe blktap2 2>/dev/null || true
+ modprobe blktap 2>/dev/null || true
+ # xenblk (frontend module) is needed in dom0, allowing it to use vbds
+ modprobe xenblk 2>/dev/null || true
+ # support xl create pv guest with qcow/qcow2 disk image
+ modprobe nbd max_part=8 2>/dev/null || true
mkdir -p /var/run/xen
if ! `${BINDIR}/xenstore-read -s / >/dev/null 2>&1`
++++++ tmp_build.patch ++++++
Index: xen-4.3.0-testing/tools/xenstore/Makefile
===================================================================
--- xen-4.3.0-testing.orig/tools/xenstore/Makefile
+++ xen-4.3.0-testing/tools/xenstore/Makefile
@@ -75,6 +75,7 @@ $(CLIENTS_DOMU): xenstore
xenstore: xenstore_client.o $(LIBXENSTORE)
$(CC) $(LDFLAGS) $< $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,--build-id=uuid $< -L. -lxenstore $(SOCKET_LIBS) -o domu-$@
xenstore-control: xenstore_control.o $(LIBXENSTORE)
$(CC) $(LDFLAGS) $< $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
@@ -124,10 +125,11 @@ install: all
$(INSTALL_PROG) xenstore-control $(DESTDIR)$(BINDIR)
$(INSTALL_PROG) xenstore $(DESTDIR)$(BINDIR)
set -e ; for c in $(CLIENTS) ; do \
- ln -f $(DESTDIR)$(BINDIR)/xenstore $(DESTDIR)$(BINDIR)/$${c} ; \
+ ln -fs /usr/bin/xenstore $(DESTDIR)/usr/bin/$${c} ; \
done
+ $(INSTALL_PROG) domu-xenstore $(DESTDIR)/bin
for client in $(CLIENTS_DOMU); do \
- $(INSTALL_PROG) $$client $(DESTDIR)/bin/$${client/domu-}; \
+ ln -fs /bin/domu-xenstore $(DESTDIR)/bin/$${client/domu-}; \
done
$(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
$(INSTALL_PROG) libxenstore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
++++++ udev-rules.patch ++++++
Index: xen-4.4.1-testing/tools/hotplug/Linux/xen-backend.rules
===================================================================
--- xen-4.4.1-testing.orig/tools/hotplug/Linux/xen-backend.rules
+++ xen-4.4.1-testing/tools/hotplug/Linux/xen-backend.rules
@@ -12,4 +12,5 @@ KERNEL=="blktap-control", NAME="xen/blkt
KERNEL=="gntdev", NAME="xen/%k", MODE="0600"
KERNEL=="pci_iomul", NAME="xen/%k", MODE="0600"
KERNEL=="tapdev[a-z]*", NAME="xen/blktap-2/tapdev%m", MODE="0600"
-SUBSYSTEM=="net", KERNEL=="vif*-emu", ACTION=="add", ENV{UDEV_CALL}="1", RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
+SUBSYSTEM=="net", KERNEL=="vif*-emu", ACTION=="add", ENV{UDEV_CALL}="1", TEST=="/proc/xen" RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
+KERNELS=="xen", KERNEL=="xvd*", SUBSYSTEM=="block", OPTIONS+="last_rule"
++++++ vif-bridge-no-iptables.patch ++++++
Index: xen-4.4.0-testing/tools/hotplug/Linux/vif-bridge
===================================================================
--- xen-4.4.0-testing.orig/tools/hotplug/Linux/vif-bridge
+++ xen-4.4.0-testing/tools/hotplug/Linux/vif-bridge
@@ -97,9 +97,9 @@ case "$command" in
;;
esac
-if [ "$type_if" = vif ]; then
- handle_iptable
-fi
+#if [ "$type_if" = vif ]; then
+# handle_iptable
+#fi
call_hooks vif post
++++++ vif-bridge-tap-fix.patch ++++++
# HG changeset patch
# User Jim Fehlig
# Date 1319581952 21600
# Node ID 74da2a3a1db1476d627f42e4a99e9e720cc6774d
# Parent 6c583d35d76dda2236c81d9437ff9d57ab02c006
Prevent vif-bridge from adding user-created tap interfaces to a bridge
Exit vif-bridge script if there is no device info in xenstore, preventing
it from adding user-created taps to bridges.
Signed-off-by: Jim Fehlig
Index: xen-4.2.0-testing/tools/hotplug/Linux/vif-bridge
===================================================================
--- xen-4.2.0-testing.orig/tools/hotplug/Linux/vif-bridge
+++ xen-4.2.0-testing/tools/hotplug/Linux/vif-bridge
@@ -32,6 +32,13 @@
dir=$(dirname "$0")
. "$dir/vif-common.sh"
+mac=$(xenstore_read_default "$XENBUS_PATH/mac" "")
+if [ -z "$mac" ]
+then
+ log debug "No device details in $XENBUS_PATH, exiting."
+ exit 0
+fi
+
bridge=${bridge:-}
bridge=$(xenstore_read_default "$XENBUS_PATH/bridge" "$bridge")
++++++ x86-cpufreq-report.patch ++++++
Index: xen-4.4.0-testing/xen/arch/x86/platform_hypercall.c
===================================================================
--- xen-4.4.0-testing.orig/xen/arch/x86/platform_hypercall.c
+++ xen-4.4.0-testing/xen/arch/x86/platform_hypercall.c
@@ -25,7 +25,7 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
@@ -601,6 +601,41 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PA
}
break;
+ case XENPF_get_cpu_freq:
+ case XENPF_get_cpu_freq_min:
+ case XENPF_get_cpu_freq_max:
+ {
+ struct vcpu *v;
+ const struct cpufreq_policy *policy;
+
+ if ( op->u.get_cpu_freq.vcpu >= current->domain->max_vcpus ||
+ !(v = current->domain->vcpu[op->u.get_cpu_freq.vcpu]) )
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ policy = per_cpu(cpufreq_cpu_policy, v->processor);
+ switch ( op->cmd & -!!policy )
+ {
+ case XENPF_get_cpu_freq:
+ op->u.get_cpu_freq.freq = policy->cur;
+ break;
+ case XENPF_get_cpu_freq_min:
+ op->u.get_cpu_freq.freq = policy->min;
+ break;
+ case XENPF_get_cpu_freq_max:
+ op->u.get_cpu_freq.freq = policy->max;
+ break;
+ default:
+ op->u.get_cpu_freq.freq = 0;
+ break;
+ }
+ if ( __copy_field_to_guest(u_xenpf_op, op, u.get_cpu_freq.freq) )
+ ret = -EFAULT;
+ }
+ break;
+
default:
ret = -ENOSYS;
break;
Index: xen-4.4.0-testing/xen/include/public/platform.h
===================================================================
--- xen-4.4.0-testing.orig/xen/include/public/platform.h
+++ xen-4.4.0-testing/xen/include/public/platform.h
@@ -527,6 +527,16 @@ struct xenpf_core_parking {
typedef struct xenpf_core_parking xenpf_core_parking_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t);
+#define XENPF_get_cpu_freq ('N' << 24)
+#define XENPF_get_cpu_freq_min (XENPF_get_cpu_freq + 1)
+#define XENPF_get_cpu_freq_max (XENPF_get_cpu_freq_min + 1)
+struct xenpf_get_cpu_freq {
+ /* IN variables */
+ uint32_t vcpu;
+ /* OUT variables */
+ uint32_t freq; /* in kHz */
+};
+
/*
* ` enum neg_errnoval
* ` HYPERVISOR_platform_op(const struct xen_platform_op*);
@@ -553,6 +563,7 @@ struct xen_platform_op {
struct xenpf_cpu_hotadd cpu_add;
struct xenpf_mem_hotadd mem_add;
struct xenpf_core_parking core_parking;
+ struct xenpf_get_cpu_freq get_cpu_freq;
uint8_t pad[128];
} u;
};
++++++ x86-dom-print.patch ++++++
Index: xen-4.3.0-testing/xen/arch/x86/domain.c
===================================================================
--- xen-4.3.0-testing.orig/xen/arch/x86/domain.c
+++ xen-4.3.0-testing/xen/arch/x86/domain.c
@@ -151,15 +151,30 @@ void dump_pageframe_info(struct domain *
printk("Memory pages belonging to domain %u:\n", d->domain_id);
- if ( d->tot_pages >= 10 )
+ if ( d->tot_pages >= 10 && d->is_dying < DOMDYING_dead )
{
printk(" DomPage list too long to display\n");
}
else
{
+ unsigned long total[PGT_type_mask
+ / (PGT_type_mask & -PGT_type_mask) + 1] = {};
+
spin_lock(&d->page_alloc_lock);
page_list_for_each ( page, &d->page_list )
{
+ unsigned int index = (page->u.inuse.type_info & PGT_type_mask)
+ / (PGT_type_mask & -PGT_type_mask);
+
+ if ( ++total[index] > 16 )
+ {
+ switch ( page->u.inuse.type_info & PGT_type_mask )
+ {
+ case PGT_none:
+ case PGT_writable_page:
+ continue;
+ }
+ }
printk(" DomPage %p: caf=%08lx, taf=%" PRtype_info "\n",
_p(page_to_mfn(page)),
page->count_info, page->u.inuse.type_info);
++++++ x86-extra-trap-info.patch ++++++
Index: xen-4.4.0-testing/xen/arch/x86/x86_64/entry.S
===================================================================
--- xen-4.4.0-testing.orig/xen/arch/x86/x86_64/entry.S
+++ xen-4.4.0-testing/xen/arch/x86/x86_64/entry.S
@@ -438,19 +438,30 @@ UNLIKELY_START(z, create_bounce_frame_ba
__UNLIKELY_END(create_bounce_frame_bad_bounce_ip)
movq %rax,UREGS_rip+8(%rsp)
ret
- _ASM_EXTABLE(.Lft2, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft3, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft4, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft5, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft6, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft7, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft8, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft9, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft10, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft11, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft12, dom_crash_sync_extable)
- _ASM_EXTABLE(.Lft13, dom_crash_sync_extable)
+ _ASM_EXTABLE(.Lft2, domain_crash_page_fault_32)
+ _ASM_EXTABLE(.Lft3, domain_crash_page_fault_24)
+ _ASM_EXTABLE(.Lft4, domain_crash_page_fault_8)
+ _ASM_EXTABLE(.Lft5, domain_crash_page_fault_16)
+ _ASM_EXTABLE(.Lft6, domain_crash_page_fault)
+ _ASM_EXTABLE(.Lft7, domain_crash_page_fault)
+ _ASM_EXTABLE(.Lft8, domain_crash_page_fault_24)
+ _ASM_EXTABLE(.Lft9, domain_crash_page_fault_16)
+ _ASM_EXTABLE(.Lft10, domain_crash_page_fault_8)
+ _ASM_EXTABLE(.Lft11, domain_crash_page_fault)
+ _ASM_EXTABLE(.Lft12, domain_crash_page_fault_8)
+ _ASM_EXTABLE(.Lft13, domain_crash_page_fault)
+domain_crash_page_fault_32:
+ addq $8,%rsi
+domain_crash_page_fault_24:
+ addq $8,%rsi
+domain_crash_page_fault_16:
+ addq $8,%rsi
+domain_crash_page_fault_8:
+ addq $8,%rsi
+domain_crash_page_fault:
+ movq %rsi,%rdi
+ call show_page_walk
ENTRY(dom_crash_sync_extable)
# Get out of the guest-save area of the stack.
GET_STACK_BASE(%rax)
++++++ x86-ioapic-ack-default.patch ++++++
Change default IO-APIC ack mode for single IO-APIC systems to old-style.
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -2035,7 +2035,10 @@ void __init setup_IO_APIC(void)
io_apic_irqs = ~PIC_IRQS;
printk("ENABLING IO-APIC IRQs\n");
- printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
+ if (!directed_eoi_enabled && !ioapic_ack_forced) {
+ ioapic_ack_new = (nr_ioapics > 1);
+ printk(" -> Using %s ACK method\n", ioapic_ack_new ? "new" : "old");
+ }
if (ioapic_ack_new) {
ioapic_level_type.ack = irq_complete_move;
++++++ xen-destdir.patch ++++++
Index: xen-4.4.0-testing/tools/xenstore/Makefile
===================================================================
--- xen-4.4.0-testing.orig/tools/xenstore/Makefile
+++ xen-4.4.0-testing/tools/xenstore/Makefile
@@ -10,6 +10,7 @@ CFLAGS += $(CFLAGS_libxenctrl)
CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm xenstore-chmod
CLIENTS += xenstore-write xenstore-ls xenstore-watch
+CLIENTS_DOMU := $(patsubst xenstore-%,domu-xenstore-%,$(CLIENTS))
XENSTORED_OBJS = xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o hashtable.o
@@ -41,7 +42,7 @@ endif
all: $(ALL_TARGETS)
.PHONY: clients
-clients: xenstore $(CLIENTS) xenstore-control
+clients: xenstore $(CLIENTS) $(CLIENTS_DOMU) xenstore-control
ifeq ($(CONFIG_SunOS),y)
xenstored_probes.h: xenstored_probes.d
@@ -69,6 +70,9 @@ xenstored.a: $(XENSTORED_OBJS)
$(CLIENTS): xenstore
ln -f xenstore $@
+$(CLIENTS_DOMU): xenstore
+ ln -f xenstore $@
+
xenstore: xenstore_client.o $(LIBXENSTORE)
$(CC) $(LDFLAGS) $< $(LDLIBS_libxenstore) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
@@ -96,7 +100,7 @@ clean:
rm -f *.a *.o *.opic *.so* xenstored_probes.h
rm -f xenstored xs_random xs_stress xs_crashme
rm -f xs_tdb_dump xenstore-control init-xenstore-domain
- rm -f xenstore $(CLIENTS)
+ rm -f xenstore $(CLIENTS) $(CLIENTS_DOMU)
$(RM) $(DEPS)
.PHONY: TAGS
@@ -113,6 +117,7 @@ install: all
$(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)
$(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR)/xenstore-compat
+ $(INSTALL_DIR) $(DESTDIR)/bin
$(INSTALL_DIR) $(DESTDIR)/var/run/xenstored
$(INSTALL_DIR) $(DESTDIR)/var/lib/xenstored
$(INSTALL_PROG) xenstored $(DESTDIR)$(SBINDIR)
@@ -121,6 +126,9 @@ install: all
set -e ; for c in $(CLIENTS) ; do \
ln -f $(DESTDIR)$(BINDIR)/xenstore $(DESTDIR)$(BINDIR)/$${c} ; \
done
+ for client in $(CLIENTS_DOMU); do \
+ $(INSTALL_PROG) $$client $(DESTDIR)/bin/$${client/domu-}; \
+ done
$(INSTALL_DIR) $(DESTDIR)$(LIBDIR)
$(INSTALL_PROG) libxenstore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
ln -sf libxenstore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)/libxenstore.so.$(MAJOR)
Index: xen-4.4.0-testing/tools/hotplug/Linux/Makefile
===================================================================
--- xen-4.4.0-testing.orig/tools/hotplug/Linux/Makefile
+++ xen-4.4.0-testing/tools/hotplug/Linux/Makefile
@@ -46,14 +46,14 @@ install: all install-initd install-scrip
.PHONY: install-initd
install-initd:
[ -d $(DESTDIR)$(INITD_DIR) ] || $(INSTALL_DIR) $(DESTDIR)$(INITD_DIR)
- [ -d $(DESTDIR)$(SYSCONFIG_DIR) ] || $(INSTALL_DIR) $(DESTDIR)$(SYSCONFIG_DIR)
+ [ -d $(DESTDIR)/var/adm/fillup-templates ] || $(INSTALL_DIR) $(DESTDIR)/var/adm/fillup-templates/
ifeq ($(CONFIG_XEND),y)
$(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)$(INITD_DIR)
endif
$(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)$(INITD_DIR)
- $(INSTALL_DATA) $(XENDOMAINS_SYSCONFIG) $(DESTDIR)$(SYSCONFIG_DIR)/xendomains
+ $(INSTALL_DATA) $(XENDOMAINS_SYSCONFIG) $(DESTDIR)/var/adm/fillup-templates/
$(INSTALL_PROG) $(XENCOMMONS_INITD) $(DESTDIR)$(INITD_DIR)
- $(INSTALL_DATA) $(XENCOMMONS_SYSCONFIG) $(DESTDIR)$(SYSCONFIG_DIR)/xencommons
+ $(INSTALL_DATA) $(XENCOMMONS_SYSCONFIG) $(DESTDIR)/var/adm/fillup-templates/
$(INSTALL_PROG) init.d/xen-watchdog $(DESTDIR)$(INITD_DIR)
.PHONY: install-scripts
Index: xen-4.4.0-testing/tools/firmware/etherboot/Makefile
===================================================================
--- xen-4.4.0-testing.orig/tools/firmware/etherboot/Makefile
+++ xen-4.4.0-testing/tools/firmware/etherboot/Makefile
@@ -28,12 +28,12 @@ all: $(ROMS)
$(MAKE) -C $D/src bin/$(*F).rom
$T:
- if ! $(FETCHER) _$T $(IPXE_TARBALL_URL); then \
- $(GIT) clone $(IPXE_GIT_URL) $D.git; \
- (cd $D.git && $(GIT) archive --format=tar --prefix=$D/ \
- $(IPXE_GIT_TAG) | gzip >../_$T); \
- rm -rf $D.git; \
- fi
+ #if ! $(FETCHER) _$T $(IPXE_TARBALL_URL); then \
+ # $(GIT) clone $(IPXE_GIT_URL) $D.git; \
+ # (cd $D.git && $(GIT) archive --format=tar --prefix=$D/ \
+ # $(IPXE_GIT_TAG) | gzip >../_$T); \
+ # rm -rf $D.git; \
+ #fi
mv _$T $T
$D/src/arch/i386/Makefile: $T Config
++++++ xen-disable-qemu-monitor.patch ++++++
CVE-2007-0998 - remote compromise of dom0
Rather than completely disabling QEMU's console (which would remove
the "sendkey" command, among other useful things), remove all console
commands that can read/write dom0's state.
Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/monitor.c
===================================================================
--- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/monitor.c
+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/monitor.c
@@ -1497,6 +1497,7 @@ static const term_cmd_t term_cmds[] = {
"device|all", "commit changes to the disk images (if -snapshot is used) or backing files" },
{ "info", "s?", do_info,
"subcommand", "show various information about the system state" },
+#ifdef CONFIG_TRUSTED_CLIENT
{ "q|quit", "", do_quit,
"", "quit the emulator" },
{ "eject", "-fB", do_eject,
@@ -1509,6 +1510,7 @@ static const term_cmd_t term_cmds[] = {
"filename", "output logs to 'filename'" },
{ "log", "s", do_log,
"item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
+#endif
{ "savevm", "s?", do_savevm,
"tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
{ "loadvm", "s", do_loadvm,
@@ -1538,8 +1540,10 @@ static const term_cmd_t term_cmds[] = {
"", "reset the system" },
{ "system_powerdown", "", do_system_powerdown,
"", "send system power down event" },
+#ifdef CONFIG_TRUSTED_CLIENT
{ "sum", "ii", do_sum,
"addr size", "compute the checksum of a memory region" },
+#endif
{ "usb_add", "s", do_usb_add,
"device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
{ "usb_del", "s", do_usb_del,
@@ -1558,6 +1562,7 @@ static const term_cmd_t term_cmds[] = {
"state", "change mouse button state (1=L, 2=M, 4=R)" },
{ "mouse_set", "i", do_mouse_set,
"index", "set which mouse device receives events" },
+#ifdef CONFIG_TRUSTED_CLIENT
#ifdef HAS_AUDIO
{ "wavcapture", "si?i?i?", do_wav_capture,
"path [frequency bits channels]",
@@ -1565,6 +1570,7 @@ static const term_cmd_t term_cmds[] = {
#endif
{ "stopcapture", "i", do_stop_capture,
"capture index", "stop capture" },
+#endif
{ "memsave", "lis", do_memory_save,
"addr size file", "save to disk virtual memory dump starting at 'addr' of size 'size'", },
{ "pmemsave", "lis", do_physical_memory_save,
@@ -1646,6 +1652,7 @@ static const term_cmd_t info_cmds[] = {
"", "show KVM information", },
{ "usb", "", usb_info,
"", "show guest USB devices", },
+#ifdef CONFIG_TRUSTED_CLIENT
{ "usbhost", "", usb_host_info,
"", "show host USB devices", },
{ "profile", "", do_info_profile,
@@ -1677,6 +1684,7 @@ static const term_cmd_t info_cmds[] = {
{ "migrate", "", do_info_migrate, "", "show migration status" },
{ "balloon", "", do_info_balloon,
"", "show balloon information" },
+#endif
{ NULL, NULL, },
};
++++++ xen-figlet-makefile.patch ++++++
Index: xen-4.4.2-testing/xen/tools/Makefile
===================================================================
--- xen-4.4.2-testing.orig/xen/tools/Makefile
+++ xen-4.4.2-testing/xen/tools/Makefile
@@ -3,10 +3,12 @@ include $(XEN_ROOT)/Config.mk
.PHONY: default
default:
+ [ -d figlet ] && $(MAKE) -C figlet
$(MAKE) symbols
.PHONY: clean
clean:
+ [ -d figlet ] && $(MAKE) -C figlet clean
rm -f *.o symbols
symbols: symbols.c
Index: xen-4.4.2-testing/xen/Makefile
===================================================================
--- xen-4.4.2-testing.orig/xen/Makefile
+++ xen-4.4.2-testing/xen/Makefile
@@ -114,12 +114,10 @@ delete-unfresh-files:
fi
.banner: Makefile
- @if which figlet >/dev/null 2>&1 ; then \
- echo " Xen $(XEN_FULLVERSION)" | figlet -f tools/xen.flf > $@.tmp; \
- else \
- echo " Xen $(XEN_FULLVERSION)" > $@.tmp; \
- fi
- @mv -f $@.tmp $@
+ $(MAKE) -C tools
+ @tools/figlet/figlet -d tools/figlet Xen $(XEN_FULLVERSION) 2>$@2 >$@1
+ @cat $@1 $@2 >$@
+ @rm -f $@1 $@2
# compile.h contains dynamic build info. Rebuilt on every 'make' invocation.
include/xen/compile.h: include/xen/compile.h.in .banner
@@ -134,8 +132,8 @@ include/xen/compile.h: include/xen/compi
-e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \
-e 's!@@changeset@@!$(shell tools/scmversion $(XEN_ROOT) || echo "unavailable")!g' \
< include/xen/compile.h.in > $@.new
- @cat .banner
- @$(PYTHON) tools/fig-to-oct.py < .banner >> $@.new
+ @grep \" .banner >> $@.new
+ @grep -v \" .banner
@mv -f $@.new $@
include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s
++++++ xen-hvm-default-bridge.patch ++++++
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/net.h
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/net.h
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/net.h
@@ -107,8 +107,8 @@ void net_host_device_add(const char *dev
void net_host_device_remove(int vlan_id, const char *device);
#ifndef DEFAULT_NETWORK_SCRIPT
-#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
-#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
+#define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
+#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/xen/qemu-ifdown"
#endif
#ifdef __sun__
#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/net.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/net.c
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/net.c
@@ -1765,9 +1765,10 @@ int net_client_init(const char *device,
}
if (get_param_value(script_arg, sizeof(script_arg), "scriptarg", p) == 0 &&
get_param_value(script_arg, sizeof(script_arg), "bridge", p) == 0) { /* deprecated; for xend compatibility */
- pstrcpy(script_arg, sizeof(script_arg), "");
+ ret = net_tap_init(vlan, device, name, ifname, setup_script, NULL, NULL);
+ } else {
+ ret = net_tap_init(vlan, device, name, ifname, setup_script, down_script, script_arg);
}
- ret = net_tap_init(vlan, device, name, ifname, setup_script, down_script, script_arg);
}
} else
#endif
Index: xen-4.4.3-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.4.3-testing/tools/python/xen/xend/image.py
@@ -912,11 +912,13 @@ class HVMImageHandler(ImageHandler):
mac = devinfo.get('mac')
if mac is None:
raise VmError("MAC address not specified or generated.")
- bridge = devinfo.get('bridge', 'xenbr0')
+ bridge = devinfo.get('bridge', None)
model = devinfo.get('model', 'rtl8139')
ret.append("-net")
- ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
- (nics, mac, model))
+ net = "nic,vlan=%d,macaddr=%s,model=%s" % (nics, mac, model)
+ if bridge:
+ net += ",bridge=%s" % bridge
+ ret.append(net)
vifname = "vif%d.%d-emu" % (self.vm.getDomid(), nics-1)
ret.append("-net")
if osdep.tapif_script is not None:
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
@@ -1,36 +1,22 @@
#!/bin/sh
-#. /etc/rc.d/init.d/functions
-#ulimit -c unlimited
-
echo 'config qemu network with xen bridge for ' $*
+# If bridge is not specified, try device with default route.
bridge=$2
+if [ -z "$bridge" ]; then
+ bridge=$(ip route list | awk '/^default / { print $NF }')
+fi
-#
-# Old style bridge setup with netloop, used to have a bridge name
-# of xenbrX, enslaving pethX and vif0.X, and then configuring
-# eth0.
-#
-# New style bridge setup does not use netloop, so the bridge name
-# is ethX and the physical device is enslaved pethX
-#
-# So if...
-#
-# - User asks for xenbrX
-# - AND xenbrX doesn't exist
-# - AND there is a ethX device which is a bridge
-#
-# ..then we translate xenbrX to ethX
-#
-# This lets old config files work without modification
-#
-if [ ! -e "/sys/class/net/$bridge" ] && [ -z "${bridge##xenbr*}" ]
+# Exit if $bridge is not a bridge. Exit with 0 status
+# so qemu-dm process is not terminated. No networking in
+# vm is bad but not catastrophic. The vm could still run
+# cpu and disk IO workloads.
+# Include an useful error message in qemu-dm log file.
+if [ ! -e "/sys/class/net/${bridge}/bridge" ]
then
- if [ -e "/sys/class/net/eth${bridge#xenbr}/bridge" ]
- then
- bridge="eth${bridge#xenbr}"
- fi
+ echo "WARNING! ${bridge} is not a bridge. qemu-ifup exiting. VM may not have a functioning networking stack."
+ exit 0
fi
ifconfig $1 0.0.0.0 up
++++++ xen-qemu-iscsi-fix.patch ++++++
Index: xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.4.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.4.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -451,7 +451,7 @@ void xenstore_parse_domain_config(int hv
char *buf = NULL;
char *fpath = NULL, *bpath = NULL, *btype = NULL,
*dev = NULL, *params = NULL, *drv = NULL;
- int i, ret, is_tap;
+ int i, j, ret, is_tap;
unsigned int len, num, hd_index, pci_devid = 0;
BlockDriverState *bs;
BlockDriver *format;
@@ -535,12 +535,7 @@ void xenstore_parse_domain_config(int hv
continue;
free(danger_type);
danger_type = xs_read(xsh, XBT_NULL, danger_buf, &len);
- if (pasprintf(&buf, "%s/params", bpath) == -1)
- continue;
- free(params);
- params = xs_read(xsh, XBT_NULL, buf, &len);
- if (params == NULL)
- continue;
+
/* read the name of the device */
if (pasprintf(&buf, "%s/type", bpath) == -1)
continue;
@@ -548,6 +543,35 @@ void xenstore_parse_domain_config(int hv
drv = xs_read(xsh, XBT_NULL, buf, &len);
if (drv == NULL)
continue;
+
+ free(params);
+ if (!strcmp(drv,"iscsi") || !strcmp(drv, "npiv") ||
+ !strcmp(drv,"dmmd")) {
+ if (pasprintf(&buf, "%s/node", bpath) == -1)
+ continue;
+
+ /* wait for block-[iscsi|npiv|dmmd] script to complete and populate the
+ * node entry. try 30 times (30 secs) */
+ for (j = 0; j < 30; j++) {
+ params = xs_read(xsh, XBT_NULL, buf, &len);
+ if (params != NULL)
+ break;
+ sleep(1);
+ }
+ if (params == NULL) {
+ fprintf(stderr, "qemu: %s device not found -- timed out \n", drv);
+ continue;
+ }
+ }
+ else
+ {
+ if (pasprintf(&buf, "%s/params", bpath) == -1)
+ continue;
+ params = xs_read(xsh, XBT_NULL, buf, &len);
+ if (params == NULL)
+ continue;
+ }
+
/* Obtain blktap sub-type prefix */
if ((!strcmp(drv, "tap") || !strcmp(drv, "qdisk")) && params[0]) {
char *offset = strchr(params, ':');
@@ -665,6 +689,12 @@ void xenstore_parse_domain_config(int hv
format = &bdrv_host_device;
else
format = &bdrv_raw;
+ } else if (!strcmp(drv,"iscsi")) {
+ format = &bdrv_raw;
+ } else if (!strcmp(drv,"npiv")) {
+ format = &bdrv_raw;
+ } else if (!strcmp(drv,"dmmd")) {
+ format = &bdrv_raw;
} else {
format = bdrv_find_format(drv);
if (!format) {
++++++ xen-updown.sh ++++++
#!/bin/bash
#
usage () {
echo $@
echo "usage: $0 [<config>] <interface> [-o <options>]"
echo ""
echo "Options are:"
echo " debug : be verbose"
echo " rc : indicates that we are called from rcnetwork"
echo ""
echo "Any another options are ignored"
exit $R_USAGE
}
xm_cmd="xm"
pidof -x /usr/sbin/xend >/dev/null 2>&1 || xm_cmd="xl"
######################################################################
# change the working direcory and source some common files
#
R_INTERNAL=1 # internal error, e.g. no config or missing scripts
cd /etc/sysconfig/network || exit $R_INTERNAL
test -f ./config && . ./config
test -f scripts/functions && . scripts/functions || exit $R_INTERNAL
######################################################################
# check arguments and how we are called (in case of links)
#
SCRIPTNAME=${0}
debug $*
case $1 in ""|-h|*help*) usage ;; esac
CONFIG="$1"
shift
if [ "x$1" != x -a "x$1" != "x-o" ] ; then
INTERFACE="$1"
else
INTERFACE="$CONFIG"
fi
shift
test "x$1" = "x-o" && shift
DEBUG=no
RUN_FROM_RC=no
while [ $# -gt 0 ]; do
case $1 in
debug) DEBUG=yes ;;
rc) RUN_FROM_RC=yes ;;
*) debug unknown option $1 ;;
esac
shift
done
# usage: ifprint message....
ifprint() {
func=$1 ; shift
test "x$func" = x && return 1
if [ "$RUN_FROM_RC" = yes -a "$INTERFACE" != all ] ; then
$func "`printf " %-9s " "$INTERFACE"`$*"
else
$func "$*"
fi
}
#
# xen related code
#
# check if xen is running
is_xend_running() {
test -x /etc/init.d/xend && \
/etc/init.d/xend status &>/dev/null && return 0
return 1
}
exit_if_xend_not_running() {
is_xend_running || {
debug "$0: xend is not running - nothing to do"
exit 0
}
}
# (modified) functions from /etc/init.d/xendomains
parseln()
{
name=${1:0:$((${#1}-36))}
name=${name%% *}
rest="${1: -36}"
id=${rest:0:4}
id=`echo $id`
mem=${rest:4:6}
mem=`echo $mem`
vcpu=${rest:10:6}
vcpu=`echo $vcpu`
state=${rest:16:11}
state=`echo $state`
tm=${rest:27}
tm=`echo $tm`
}
xm_list()
{
TERM=vt100 ${xm_cmd} list | grep -v '^Name *ID'
}
# For the specified vm, return a list of vifs that are connected to $INTERFACE
list_vifs()
{
id=$1
vifs=()
for vif in $(ls -1 "/sys/class/net/$INTERFACE/brif/" 2>/dev/null) ; do
eval BRIDGE_PORTS="" `grep "^[[:space:]]*BRIDGE_PORTS=" \
"/etc/sysconfig/network/ifcfg-$INTERFACE" 2>/dev/null`
for p in $BRIDGE_PORTS ; do
test "x$p" = "x$vif" && continue 2
done
case $vif in
(tap${id}\.*|vif${id}\.*)
vifs=(${vifs[@]} ${vif})
;;
esac
done
echo "${vifs[@]}"
}
# Write list of concerned vifs to state file
save_sysconfig_state()
{
[ -d "${RUN_FILES_BASE}/xen/" ] || \
mkdir -p "${RUN_FILES_BASE}/xen/" || return 1
rm -f "${RUN_FILES_BASE}/xen/$INTERFACE" && {
echo "VIFS='${vifs[@]}'"
} > "${RUN_FILES_BASE}/xen/$INTERFACE"
}
case $SCRIPTNAME in
*if-up.d*)
exit_if_xend_not_running
if test -f "${RUN_FILES_BASE}/xen/$INTERFACE" ; then
. "${RUN_FILES_BASE}/xen/$INTERFACE"
for vif in ${VIFS}; do
test -d "/sys/class/net/${vif}" || continue
test -d "/sys/class/net/${INTERFACE}/brif/${vif}" && \
continue
if ! is_iface_up ${vif} ; then
ip link set dev ${vif} up || continue
fi
brctl addif ${INTERFACE} ${vif} &>/dev/null
done
# remove sysconfig state
rm -f "${RUN_FILES_BASE}/xen/$INTERFACE"
fi
;;
*if-down.d*)
exit_if_xend_not_running
test -d "/sys/class/net/$INTERFACE/brif/" || exit 0
# Remember vifs attached to $INTERFACE
vifs=()
num=0
while read LN; do
parseln "$LN"
[ "$id" = 0 ] && continue
[ -z "$state" ] && continue
vifs=(${vifs[@]} $(list_vifs $id))
done < <(xm_list)
[ -z "${vifs[*]}" ] || save_sysconfig_state
;;
*)
usage
;;
esac
++++++ xen-watchdog.service ++++++
[Unit]
Description=Xen-watchdog - run xen watchdog daemon
After=xend.service
ConditionPathExists=/proc/xen
[Service]
Type=forking
ExecStart=/usr/sbin/xenwatchdogd 30 15
KillSignal=USR1
[Install]
WantedBy=multi-user.target
++++++ xen-xmexample.patch ++++++
Change various example paths in the config files to match SUSE.
Index: xen-4.3.0-testing/tools/examples/xmexample1
===================================================================
--- xen-4.3.0-testing.orig/tools/examples/xmexample1
+++ xen-4.3.0-testing/tools/examples/xmexample1
@@ -7,11 +7,17 @@
#============================================================================
#----------------------------------------------------------------------------
-# Kernel image file.
-kernel = "/boot/vmlinuz-2.6.10-xenU"
-
-# Optional ramdisk.
-#ramdisk = "/boot/initrd.gz"
+# Kernel image file and (optional) ramdisk (initrd).
+kernel = "/boot/vmlinuz-xen"
+ramdisk = "/boot/initrd-xen"
+
+# Or use a bootloader instead of kernel/ramdisk to get the kernel from domU FS
+# domUloader bootloader example:
+#bootloader = "/usr/lib/xen/boot/domUloader.py"
+#bootentry = "hda2:/vmlinuz-xen,/initrd-xen"
+# pygrub bootloader example:
+#bootloader="/usr/bin/pygrub"
+#bootargs=""
# The domain build function. Default is 'linux'.
#builder='linux'
@@ -49,11 +55,11 @@ name = "ExampleDomain"
#
# or optionally override backend, bridge, ip, mac, script, type, or vifname:
#
-# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+# vif = [ 'mac=00:16:3e:00:00:11, bridge=br0' ]
#
# or more than one interface may be configured:
#
-# vif = [ '', 'bridge=xenbr1' ]
+# vif = [ '', 'bridge=br1' ]
vif = [ '' ]
@@ -117,7 +123,7 @@ disk = [ 'phy:hda1,hda1,w' ]
#hostname= "vm%d" % vmid
# Set root device.
-root = "/dev/hda1 ro"
+root = "/dev/hda1"
# Root device for nfs.
#root = "/dev/nfs"
@@ -126,8 +132,8 @@ root = "/dev/hda1 ro"
# Root directory on the nfs server.
#nfs_root = '/full/path/to/root/directory'
-# Sets runlevel 4.
-extra = "4"
+# Extra arguments to pass to the kernel.
+extra = ""
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
Index: xen-4.3.0-testing/tools/examples/xmexample2
===================================================================
--- xen-4.3.0-testing.orig/tools/examples/xmexample2
+++ xen-4.3.0-testing/tools/examples/xmexample2
@@ -35,11 +35,17 @@ xm_vars.var('vmid',
xm_vars.check()
#----------------------------------------------------------------------------
-# Kernel image file.
-kernel = "/boot/vmlinuz-2.6.10-xenU"
-
-# Optional ramdisk.
-#ramdisk = "/boot/initrd.gz"
+# Kernel image file and (optional) ramdisk (initrd).
+kernel = "/boot/vmlinuz-xen"
+ramdisk = "/boot/initrd-xen"
+
+# Or use a bootloader instead of kernel/ramdisk to get the kernel from domU FS
+# domUloader bootloader example:
+#bootloader = "/usr/lib/xen/boot/domUloader.py"
+#bootentry = "hda2:/vmlinuz-xen,/initrd-xen"
+# pygrub bootloader example:
+#bootloader="/usr/bin/pygrub"
+#bootargs=""
# The domain build function. Default is 'linux'.
#builder='linux'
@@ -80,11 +86,11 @@ vcpus = 4 # make your domain a 4-way
#
# or optionally override backend, bridge, ip, mac, script, type, or vifname:
#
-# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+# vif = [ 'mac=00:16:3e:00:00:11, bridge=br0' ]
#
# or more than one interface may be configured:
#
-# vif = [ '', 'bridge=xenbr1' ]
+# vif = [ '', 'bridge=br1' ]
vif = [ '' ]
@@ -153,7 +159,7 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid),
#hostname= "vm%d" % vmid
# Set root device.
-root = "/dev/sda1 ro"
+root = "/dev/sda1"
# Root device for nfs.
#root = "/dev/nfs"
@@ -162,8 +168,8 @@ root = "/dev/sda1 ro"
# Root directory on the nfs server.
#nfs_root = '/full/path/to/root/directory'
-# Sets runlevel 4 and the device for /usr.
-extra = "4 VMID=%d usr=/dev/sda6" % vmid
+# Sets the device for /usr.
+extra = "VMID=%d usr=/dev/sda6" % vmid
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
Index: xen-4.3.0-testing/tools/examples/xmexample3
===================================================================
--- xen-4.3.0-testing.orig/tools/examples/xmexample3
+++ xen-4.3.0-testing/tools/examples/xmexample3
@@ -35,11 +35,17 @@ xm_vars.var('vmid',
xm_vars.check()
#----------------------------------------------------------------------------
-# Kernel image file.
-kernel = "/path/to/domU/kernel"
+# Kernel image file and (optional) ramdisk (initrd).
+kernel = "/boot/vmlinuz-xen"
+ramdisk = "/boot/initrd-xen"
-# Optional ramdisk.
-#ramdisk = "/boot/initrd.gz"
+# Or use a bootloader instead of kernel/ramdisk to get the kernel from domU FS
+# domUloader bootloader example:
+#bootloader = "/usr/lib/xen/boot/domUloader.py"
+#bootentry = "hda2:/vmlinuz-xen,/initrd-xen"
+# pygrub bootloader example:
+#bootloader="/usr/bin/pygrub"
+#bootargs=""
# The domain build function. Default is 'linux'.
#builder='linux'
Index: xen-4.3.0-testing/tools/examples/xmexample.hvm
===================================================================
--- xen-4.3.0-testing.orig/tools/examples/xmexample.hvm
+++ xen-4.3.0-testing/tools/examples/xmexample.hvm
@@ -64,11 +64,26 @@ name = "ExampleHVMDomain"
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
-# Optionally define mac and/or bridge for the network interfaces.
-# Random MACs are assigned if not given.
-#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
-# type=ioemu specify the NIC is an ioemu device not netfront
-vif = [ 'type=ioemu, bridge=xenbr0' ]
+#----------------------------------------------------------------------------
+# Define network interfaces.
+
+# By default, no network interfaces are configured. You may have one created
+# with sensible defaults using an empty vif clause:
+#
+# vif = [ '' ]
+#
+# or optionally override backend, bridge, ip, mac, script, type, model,
+# or vifname.
+#
+# An emulated RealTek 8139 network interface can be configured with:
+#
+# vif = [ 'mac=00:16:3e:00:00:11, type=ioemu, model=rtl8139, bridge=br0' ]
+#
+# A para-virtual network interface can be configured with:
+#
+# vif = [ 'mac=00:16:3e:00:00:11, type=netfront, bridge=br0' ]
+#
+vif = [ '' ]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
@@ -78,7 +93,7 @@ vif = [ 'type=ioemu, bridge=xenbr0' ]
# and MODE is r for read-only, w for read-write.
#disk = [ 'phy:hda1,hda1,r' ]
-disk = [ 'file:/var/images/min-el3-i386.img,hda,w', ',hdc:cdrom,r' ]
+disk = [ 'file:/var/lib/xen/images/disk.img,ioemu:hda,w', ',hdc:cdrom,r' ]
#----------------------------------------------------------------------------
# Configure the behaviour when a domain exits. There are three 'reasons'
Index: xen-4.3.0-testing/docs/man/xmdomain.cfg.pod.5
===================================================================
--- xen-4.3.0-testing.orig/docs/man/xmdomain.cfg.pod.5
+++ xen-4.3.0-testing/docs/man/xmdomain.cfg.pod.5
@@ -38,13 +38,13 @@ file.
The kernel image for the domain. The format of the parameter is the
fully qualified path to the kernel image file,
-i.e. I.
+i.e. I.
=item B<ramdisk>
The initial ramdisk for the domain. The format of the parameter is
-the fully qualified path to the initrd, i.e. I. On
+the fully qualified path to the initrd, i.e. I. On
many Linux distros you will not need a ramdisk if using the default
xen kernel.
@@ -321,14 +321,14 @@ configured. They should not be consider
=item I<A Loopback File as Root>
- kernel = "/boot/vmlinuz-2.6-xenU"
+ kernel = "/boot/vmlinuz-xen"
memory = 128
name = "MyLinux"
- root = "/dev/hda1 ro"
- disk = [ "file:/var/xen/mylinux.img,hda1,w" ]
+ root = "/dev/hda1"
+ disk = [ "file:/var/lib/xen/images/MyLinux/hda1,hda1,w" ]
This creates a domain called MyLinux with 128 MB of memory using a
-default xen kernel, and the file /var/xen/mylinux.img loopback mounted
+default xen kernel, and the file hda1 loopback mounted
at hda1, which is the root filesystem.
=item I<NFS Root>
Index: xen-4.3.0-testing/docs/man/xm.pod.1
===================================================================
--- xen-4.3.0-testing.orig/docs/man/xm.pod.1
+++ xen-4.3.0-testing/docs/man/xm.pod.1
@@ -165,8 +165,8 @@ soon as it is run.
=item I<without config file>
- xm create /dev/null ramdisk=initrd.img \
- kernel=/boot/vmlinuz-2.6.12.6-xenU \
+ xm create /dev/null ramdisk=initrd-xen \
+ kernel=/boot/vmlinuz-xen \
name=ramdisk vif='' vcpus=1 \
memory=64 root=/dev/ram0
Index: xen-4.3.0-testing/tools/examples/xmexample.hvm-stubdom
===================================================================
--- xen-4.3.0-testing.orig/tools/examples/xmexample.hvm-stubdom
+++ xen-4.3.0-testing/tools/examples/xmexample.hvm-stubdom
@@ -55,11 +55,26 @@ name = "xmexample.hvm"
#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
-# Optionally define mac and/or bridge for the network interfaces.
-# Random MACs are assigned if not given.
-#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
-# type=ioemu specify the NIC is an ioemu device not netfront
-vif = [ 'type=ioemu, bridge=xenbr0' ]
+#----------------------------------------------------------------------------
+# Define network interfaces.
+
+# By default, no network interfaces are configured. You may have one created
+# with sensible defaults using an empty vif clause:
+#
+# vif = [ '' ]
+#
+# or optionally override backend, bridge, ip, mac, script, type, model,
+# or vifname.
+#
+# An emulated RealTek 8139 network interface can be configured with:
+#
+# vif = [ 'mac=00:16:3e:00:00:11, type=ioemu, model=rtl8139, bridge=br0' ]
+#
+# A para-virtual network interface can be configured with:
+#
+# vif = [ 'mac=00:16:3e:00:00:11, type=netfront, bridge=br0' ]
+#
+vif = [ '' ]
#----------------------------------------------------------------------------
# Define the disk devices you want the domain to have access to, and
Index: xen-4.3.0-testing/tools/examples/xmexample.pv-grub
===================================================================
--- xen-4.3.0-testing.orig/tools/examples/xmexample.pv-grub
+++ xen-4.3.0-testing/tools/examples/xmexample.pv-grub
@@ -53,11 +53,11 @@ name = "ExampleDomain"
#
# or optionally override backend, bridge, ip, mac, script, type, or vifname:
#
-# vif = [ 'mac=00:16:3e:00:00:11, bridge=xenbr0' ]
+# vif = [ 'mac=00:16:3e:00:00:11, bridge=br0' ]
#
# or more than one interface may be configured:
#
-# vif = [ '', 'bridge=xenbr1' ]
+# vif = [ '', 'bridge=br1' ]
vif = [ '' ]
Index: xen-4.3.0-testing/docs/man/xl.pod.1
===================================================================
--- xen-4.3.0-testing.orig/docs/man/xl.pod.1
+++ xen-4.3.0-testing/docs/man/xl.pod.1
@@ -12,7 +12,8 @@ The B<xl> program is the new tool for ma
domains. The program can be used to create, pause, and shutdown
domains. It can also be used to list current domains, enable or pin
VCPUs, and attach or detach virtual block devices.
-The old B<xm> tool is deprecated and should not be used.
+The B<xm> tool continues to be supported on SLE11 platforms
+and should still be used.
The basic structure of every B<xl> command is almost always:
++++++ xen.migrate.tools-xend_move_assert_to_exception_block.patch ++++++
user: Olaf Hering
date: Thu Mar 28 15:36:02 2013 +0100
files: tools/python/xen/xend/XendCheckpoint.py
description:
tools/xend: move assert to exception block
The two assert in restore trigger sometimes after hundreds of
migrations. If they trigger the destination host will not destroy the
newly created, still empty guest. After a second migration attempt to
this host there will be two guets with the same name and uuid. This
situation is poorly handled by the xm tools.
With this change the guest will be destroyed.
Signed-off-by: Olaf Hering
---
tools/python/xen/xend/XendCheckpoint.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -267,9 +267,6 @@ def restore(xd, fd, dominfo = None, paus
store_port = dominfo.getStorePort()
console_port = dominfo.getConsolePort()
- assert store_port
- assert console_port
-
# if hvm, pass mem size to calculate the store_mfn
if is_hvm:
apic = int(dominfo.info['platform'].get('apic', 0))
@@ -281,6 +278,9 @@ def restore(xd, fd, dominfo = None, paus
pae = 0
try:
+ assert store_port
+ assert console_port
+
restore_image = image.create(dominfo, dominfo.info)
memory = restore_image.getRequiredAvailableMemory(
dominfo.info['memory_dynamic_max'] / 1024)
++++++ xen2libvirt.py ++++++
#!/usr/bin/env python
#
# Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# 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
# .
#
# Authors:
# Jim Fehlig
#
# Read native Xen configuration format, convert to libvirt domXML, and
# import (virsh define <xml>) into libvirt.
import sys
import os
import argparse
import re
from xml.etree import ElementTree
try:
import libvirt
except ImportError:
print 'Unable to import the libvirt module. Is libvirt-python installed?'
sys.exit(1)
parser = argparse.ArgumentParser(description='Import Xen domain configuration into libvirt')
parser.add_argument('-c', '--convert-only', help='Convert Xen domain configuration into libvirt domXML, but do not import into libvirt', action='store_true', dest='convert_only')
parser.add_argument('-r', '--recursive', help='Operate recursivelly on all Xen domain configuration rooted at path', action='store_true')
parser.add_argument('-f', '--format', help='Format of Xen domain configuration. Supported formats are xm and sexpr', choices=['xm', 'sexpr'], default=None)
parser.add_argument('-v', '--verbose', help='Print information about the import process', action='store_true')
parser.add_argument('path', help='Path to Xen domain configuration')
def print_verbose(msg):
if args.verbose:
print msg
def check_config(path, config):
isbinary = os.system('file -b ' + path + ' | grep text > /dev/null')
if isbinary:
print('Skipping %s (not a valid Xen configuration file)' % path)
return 'unknown'
for line in config.splitlines():
if len(line) == 0 or line.startswith('#'):
continue
if line.startswith('
#include
#include
+#ifdef HAVE_XEN_PVONHVM_UNPLUG
+#include
+#endif
#ifdef __ia64__
#include
#endif
@@ -290,6 +293,18 @@ static int check_platform_magic(struct d
short magic, unplug = 0;
char protocol, *p, *q, *err;
+#ifdef HAVE_XEN_PVONHVM_UNPLUG
+ if (xen_pvonhvm_unplug) {
+ /* Use kernel cmdline setting */
+ if (dev_unplug)
+ printk(KERN_INFO DRV_NAME ": ignoring option dev_unplug=%s \n", dev_unplug);
+ dev_unplug = NULL;
+ if (xen_pvonhvm_unplugged_disks)
+ unplug |= UNPLUG_ALL_IDE_DISKS | UNPLUG_AUX_IDE_DISKS;
+ if (xen_pvonhvm_unplugged_nics)
+ unplug |= UNPLUG_ALL_NICS;
+ } else
+#endif
/* Unconditionally unplug everything */
if (!dev_unplug)
unplug = UNPLUG_ALL;
++++++ xencommons.service ++++++
[Unit]
Description=Xencommons - Script to start and stop xenstored and xenconsoled
ConditionPathExists=/proc/xen
# Make sure network (for bridge) and remote mounts (for xendomains) are available ...
After=network-online.target
After=remote-fs.target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
ExecStart=-/etc/init.d/xencommons start
ExecStop=/etc/init.d/xencommons stop
KillMode=process
[Install]
WantedBy=multi-user.target
++++++ xenconsole-no-multiple-connections.patch ++++++
Index: xen-4.4.0-testing/tools/console/client/main.c
===================================================================
--- xen-4.4.0-testing.orig/tools/console/client/main.c
+++ xen-4.4.0-testing/tools/console/client/main.c
@@ -96,6 +96,7 @@ static int get_pty_fd(struct xs_handle *
* Assumes there is already a watch set in the store for this path. */
{
struct timeval tv;
+ struct flock lock;
fd_set watch_fdset;
int xs_fd = xs_fileno(xs), pty_fd = -1;
int start, now;
@@ -119,6 +120,14 @@ static int get_pty_fd(struct xs_handle *
pty_fd = open(pty_path, O_RDWR | O_NOCTTY);
if (pty_fd == -1)
warn("Could not open tty `%s'", pty_path);
+ else {
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ if (fcntl(pty_fd, F_SETLK, &lock) != 0)
+ err(errno, "Could not lock tty '%s'",
+ pty_path);
+ }
}
free(pty_path);
}
++++++ xend-32on64-extra-mem.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -3000,7 +3000,7 @@ class XendDomainInfo:
self.guest_bitsize = self.image.getBitSize()
# Make sure there's enough RAM available for the domain
- balloon.free(memory + shadow + vtd_mem, self)
+ balloon.free(memory + shadow + vtd_mem + 512, self)
# Set up the shadow memory
shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024)
++++++ xend-change_home_server.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -3174,6 +3174,11 @@ class XendDomainInfo:
self._cleanup_phantom_devs(paths)
self._cleanupVm()
+ if "change_home_server" in self.info:
+ chs = self.info["change_home_server"]
+ if (type(chs) is str and chs == "False") or \
+ (type(chs) is bool and chs is False):
+ self.setChangeHomeServer(None)
if ("transient" in self.info["other_config"] and \
bool(self.info["other_config"]["transient"])) or \
("change_home_server" in self.info and \
++++++ xend-check_device_status.patch ++++++
Improve check_device_status to handle HA cases
In HA environment, sometimes xenstore status has changed but ev.wait() cannot
get the signal, it will wait until timeout, thus incorrect device status is
returned. To fix this problem, we do not depend on ev.wait() result, but read
xenstore directly to get correct device status.
Index: xen-4.2.0-testing/tools/python/xen/xend/server/DevController.py
===================================================================
--- xen-4.2.0-testing.orig/tools/python/xen/xend/server/DevController.py
+++ xen-4.2.0-testing/tools/python/xen/xend/server/DevController.py
@@ -149,7 +149,10 @@ class DevController:
(status, err) = self.waitForBackend(devid)
if status == Timeout:
- self.destroyDevice(devid, False)
+ #Clean timeout backend resource
+ dev = self.convertToDeviceNumber(devid)
+ self.writeBackend(dev, HOTPLUG_STATUS_NODE, HOTPLUG_STATUS_ERROR)
+ self.destroyDevice(devid, True)
raise VmError("Device %s (%s) could not be connected. "
"Hotplug scripts not working." %
(devid, self.deviceClass))
@@ -554,7 +557,17 @@ class DevController:
xswatch(statusPath, hotplugStatusCallback, ev, result)
- ev.wait(DEVICE_CREATE_TIMEOUT)
+ for i in range(1, 50):
+ ev.wait(DEVICE_CREATE_TIMEOUT/50)
+ status = xstransact.Read(statusPath)
+ if status is not None:
+ if status == HOTPLUG_STATUS_ERROR:
+ result['status'] = Error
+ elif status == HOTPLUG_STATUS_BUSY:
+ result['status'] = Busy
+ else:
+ result['status'] = Connected
+ break
err = xstransact.Read(backpath, HOTPLUG_ERROR_NODE)
@@ -571,7 +584,12 @@ class DevController:
xswatch(statusPath, deviceDestroyCallback, ev, result)
- ev.wait(DEVICE_DESTROY_TIMEOUT)
+ for i in range(1, 50):
+ ev.wait(DEVICE_DESTROY_TIMEOUT/50)
+ status = xstransact.Read(statusPath)
+ if status is None:
+ result['status'] = Disconnected
+ break
return result['status']
++++++ xend-checkpoint-rename.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -190,7 +190,7 @@ def save(fd, dominfo, network, live, dst
dominfo.destroy()
dominfo.testDeviceComplete()
try:
- dominfo.setName(domain_name, False)
+ dominfo.setName(domain_name)
except VmError:
# Ignore this. The name conflict (hopefully) arises because we
# are doing localhost migration; if we are doing a suspend of a
++++++ xend-config-enable-dump-comment.patch ++++++
bnc#684305
---
tools/examples/xend-config.sxp | 3 +++
1 file changed, 3 insertions(+)
Index: xen-4.2.0-testing/tools/examples/xend-config.sxp
===================================================================
--- xen-4.2.0-testing.orig/tools/examples/xend-config.sxp
+++ xen-4.2.0-testing/tools/examples/xend-config.sxp
@@ -250,6 +250,9 @@
(dom0-cpus 0)
# Whether to enable core-dumps when domains crash.
+# This setting overrides the per-domain dump value 'on_crash' and causes a
+# core dump on all crashed domains. For finer grain control, it is best to
+# disable this setting (which is default) and use the per-domain controls.
#(enable-dump no)
# The tool used for initiating virtual TPM migration
++++++ xend-config.patch ++++++
Index: xen-4.2.0-testing/tools/hotplug/Linux/init.d/sysconfig.xendomains
===================================================================
--- xen-4.2.0-testing.orig/tools/hotplug/Linux/init.d/sysconfig.xendomains
+++ xen-4.2.0-testing/tools/hotplug/Linux/init.d/sysconfig.xendomains
@@ -98,7 +98,6 @@ XENDOMAINS_RESTORE=true
# Note that the script tries to be clever if both RESTORE and AUTO are
# set: It will first restore saved domains and then only start domains
# in AUTO which are not running yet.
-# Note that the name matching is somewhat fuzzy.
#
XENDOMAINS_AUTO=/etc/xen/auto
Index: xen-4.2.0-testing/tools/examples/xend-config.sxp
===================================================================
--- xen-4.2.0-testing.orig/tools/examples/xend-config.sxp
+++ xen-4.2.0-testing/tools/examples/xend-config.sxp
@@ -58,11 +58,12 @@
#(xend-http-server no)
-#(xend-unix-server no)
+(xend-unix-server yes)
#(xend-tcp-xmlrpc-server no)
#(xend-unix-xmlrpc-server yes)
+# Only enable xend-relocation-server on trusted networks as it lacks
+# encryption and authentication.
#(xend-relocation-server no)
-(xend-relocation-server yes)
#(xend-relocation-ssl-server no)
#(xend-udev-event-server no)
@@ -170,7 +171,12 @@
# two fake interfaces per guest domain. To do things like this, write
# yourself a wrapper script, and call network-bridge from it, as appropriate.
#
-(network-script network-bridge)
+# SUSE users note:
+# On openSUSE >= 11.1 and SLES >= 11, networks should be configured using
+# native platform tool - YaST. vif-bridge and qemu-ifup can be used to
+# connect vifs to the YaST-managed networks.
+#(network-script network-bridge)
+(network-script )
# The script used to control virtual interfaces. This can be overridden on a
# per-vif basis when creating a domain or a configuring a new vif. The
@@ -203,7 +209,7 @@
# dom0-min-mem is the lowest permissible memory level (in MB) for dom0.
# This is a minimum both for auto-ballooning (as enabled by
# enable-dom0-ballooning below) and for xm mem-set when applied to dom0.
-(dom0-min-mem 196)
+(dom0-min-mem 512)
# Whether to enable auto-ballooning of dom0 to allow domUs to be created.
# If enable-dom0-ballooning = no, dom0 will never balloon out.
++++++ xend-console-port-restore.patch ++++++
Pass console_port to completeRestore() so that console/port is written to
xenstore. See bnc#706574
From: Chunyan Liu
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -347,8 +347,7 @@ def restore(xd, fd, dominfo = None, paus
restore_image.setCpuid()
# xc_restore will wait for source to close connection
-
- dominfo.completeRestore(handler.store_mfn, handler.console_mfn)
+ dominfo.completeRestore(handler.store_mfn, handler.console_mfn, console_port)
#
# We shouldn't hold the domains_lock over a waitForDevices
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -3083,7 +3083,7 @@ class XendDomainInfo:
# TODO: recategorise - called from XendCheckpoint
#
- def completeRestore(self, store_mfn, console_mfn):
+ def completeRestore(self, store_mfn, console_mfn, console_port):
log.debug("XendDomainInfo.completeRestore")
@@ -3094,6 +3094,7 @@ class XendDomainInfo:
self.image = image.create(self, self.info)
if self.image:
self.image.createDeviceModel(True)
+ self.console_port = console_port
self._storeDomDetails()
self._registerWatches()
self.refreshShutdown()
++++++ xend-core-dump-loc.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -2339,7 +2339,7 @@ class XendDomainInfo:
# To prohibit directory traversal
based_name = os.path.basename(self.info['name_label'])
- coredir = "/var/xen/dump/%s" % (based_name)
+ coredir = "/var/lib/xen/dump/%s" % (based_name)
if not os.path.exists(coredir):
try:
mkdir.parents(coredir, stat.S_IRWXU)
++++++ xend-cpuinfo-model-name.patch ++++++
References: bnc#814709
For cpus that contain additional ':' characters in their name
Index: xen-4.4.0-testing/tools/python/xen/xend/osdep.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/osdep.py
+++ xen-4.4.0-testing/tools/python/xen/xend/osdep.py
@@ -143,10 +143,14 @@ def _linux_get_cpuinfo():
d = {}
for line in f:
keyvalue = line.split(':')
- if len(keyvalue) != 2:
+ if len(keyvalue) < 2:
continue
key = keyvalue[0].strip()
- val = keyvalue[1].strip()
+ for i in range(1, len(keyvalue)):
+ if i == 1:
+ val = keyvalue[i].lstrip()
+ else:
+ val = val + ":" + keyvalue[i]
if key == 'processor':
if p != -1:
cpuinfo[p] = d
++++++ xend-del_usb_xend_entry.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1300,8 +1300,15 @@ class XendDomainInfo:
frontpath = self.getDeviceController(deviceClass).frontendPath(dev)
backpath = xstransact.Read(frontpath, "backend")
thread.start_new_thread(self.getDeviceController(deviceClass).finishDeviceCleanup, (backpath, path))
-
- rc = self.getDeviceController(deviceClass).destroyDevice(devid, force)
+ if deviceClass =='vusb':
+ dev = self.getDeviceController(deviceClass).convertToDeviceNumber(devid)
+ state = self.getDeviceController(deviceClass).readBackend(dev, 'state')
+ if state == '1':
+ rc = self.getDeviceController(deviceClass).destroyDevice(devid, True)
+ else:
+ rc = self.getDeviceController(deviceClass).destroyDevice(devid, force)
+ else:
+ rc = self.getDeviceController(deviceClass).destroyDevice(devid, force)
if not force and rm_cfg:
# The backend path, other than the device itself,
# has to be passed because its accompanied frontend
++++++ xend-devid-or-name.patch ++++++
# HG changeset patch
# User Jim Fehlig
# Date 1284948067 21600
# Node ID 4674ad11feef87a6a57b99313966e0e121588e1c
# Parent 5393151a737b023476f4e571effc547e758cf8c8
xend: Fix device_configure
The semantics of XendDomainInfo.py:device_configure() changed with xen upstream
c/s 19610. Previously this method would take a devid in actual id *or* name
form, e.g. it would accept '5632' or 'hdc'. This patch restores that behavior.
Signed-off-by: Jim Fehlig
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1205,6 +1205,9 @@ class XendDomainInfo:
except ValueError:
pass
devid = dev_control.convertToDeviceNumber(dev)
+ else:
+ # devid could be a name, e.g. hdc
+ devid = dev_control.convertToDeviceNumber(devid)
dev_info = self._getDeviceInfo_vbd(devid)
if dev_info is None:
raise VmError("Device %s not connected" % devid)
++++++ xend-disable-internal-logrotate.patch ++++++
Disable internal logging and enable the logrotate.conf from the xen package.
This allows larger xend.log files
---
tools/python/xen/xend/XendLogging.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: xen-4.2.0-testing/tools/python/xen/xend/XendLogging.py
===================================================================
--- xen-4.2.0-testing.orig/tools/python/xen/xend/XendLogging.py
+++ xen-4.2.0-testing/tools/python/xen/xend/XendLogging.py
@@ -76,7 +76,7 @@ if 'TRACE' not in logging.__dict__:
log = logging.getLogger("xend")
-MAX_BYTES = 1 << 20 # 1MB
+MAX_BYTES = 0
BACKUP_COUNT = 5
STDERR_FORMAT = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
++++++ xend-domain-lock-sfex.patch ++++++
Index: xen-4.4.0-testing/tools/examples/xend-config.sxp
===================================================================
--- xen-4.4.0-testing.orig/tools/examples/xend-config.sxp
+++ xen-4.4.0-testing/tools/examples/xend-config.sxp
@@ -357,7 +357,7 @@
# path /<xend-domain-lock-path>/<vm-uuid>
# Return 0 on success, non-zero on error.
#
-# lock-util [-s] path"
+# lock-util [-s] -i <vm uuid> path"
# -s Lock status. If lock is acquired, print any contents
# on stdout and return 0. Return non-zero if lock is
# available.
@@ -383,6 +383,11 @@
#
#(xend-domain-lock-utility domain-lock)
+# Some locking mechanism provide cluster wide locking service like sfex.
+# And that requires a shared locking device.
+#(xend-domain-lock-utility domain-lock-sfex)
+#(xend-domain-lock-device "/dev/iwmvg/hbdevice")
+
# If we have a very big scsi device configuration, start of xend is slow,
# because xend scans all the device paths to build its internal PSCSI device
# list. If we need only a few devices for assigning to a guest, we can reduce
Index: xen-4.4.0-testing/tools/hotplug/Linux/Makefile
===================================================================
--- xen-4.4.0-testing.orig/tools/hotplug/Linux/Makefile
+++ xen-4.4.0-testing/tools/hotplug/Linux/Makefile
@@ -24,6 +24,7 @@ XEN_SCRIPTS += external-device-migrate
XEN_SCRIPTS += vscsi
XEN_SCRIPTS += block-iscsi
XEN_SCRIPTS += domain-lock vm-monitor
+XEN_SCRIPTS += domain-lock-sfex
XEN_SCRIPTS += $(XEN_SCRIPTS-y)
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
Index: xen-4.4.0-testing/tools/hotplug/Linux/domain-lock
===================================================================
--- xen-4.4.0-testing.orig/tools/hotplug/Linux/domain-lock
+++ xen-4.4.0-testing/tools/hotplug/Linux/domain-lock
@@ -4,7 +4,7 @@ basedir=$(dirname "$0")
usage() {
echo "usage: domain-lock [-l|-u] -n <vm name> -i <vm uuid> -p <physical host> path"
- echo "usage: domain-lock [-s] path"
+ echo "usage: domain-lock [-s] -i <vm uuid> path"
echo ""
echo "-l lock"
echo "-u unlock"
Index: xen-4.4.0-testing/tools/hotplug/Linux/domain-lock-sfex
===================================================================
--- /dev/null
+++ xen-4.4.0-testing/tools/hotplug/Linux/domain-lock-sfex
@@ -0,0 +1,166 @@
+#!/bin/bash
+
+# pre-condition
+# 1. device is ready: logical volume activated if used
+# 2. device already initialized
+# 3. index is assigned correctly
+
+#error code:
+# 0: success
+# 1: error
+
+if [ `uname -m` = "x86_64" ]; then
+ SFEX_DAEMON=/usr/lib64/heartbeat/sfex_daemon
+else
+ SFEX_DAEMON=/usr/lib/heartbeat/sfex_daemon
+fi
+SFEX_INIT=/usr/sbin/sfex_init
+COLLISION_TIMEOUT=1
+LOCK_TIMEOUT=3
+MONITOR_INTERVAL=2
+LOCAL_LOCK_FILE=/var/lock/sfex
+
+usage() {
+ echo "usage: domain-lock-sfex [-l|-u|-s] -i <vm uuid> -x <sfex device>"
+ echo ""
+ echo "-l lock"
+ echo "-u unlock"
+ echo "-s status (default)"
+ echo "-i Virtual Machine Id or UUID"
+ echo "-x SFEX device which used for sfex lock"
+ exit 1
+}
+
+get_lock_host() {
+ local rscname=$1
+ local device=$2
+ r=`$SFEX_DAEMON -s -u $rscname $device`
+ echo $r
+}
+
+get_status() {
+ local rscname=$1
+ if /usr/bin/pgrep -f "$SFEX_DAEMON .* ${rscname} " > /dev/null 2>&1; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+acquire_lock() {
+ local rscname=$1
+ local device=$2
+ get_status $rscname
+ ## We assume xend will take care to avoid starting same VM twice on the same machine.
+ if [ $? -eq 0 ]; then
+ return 0
+ fi
+ $SFEX_DAEMON -c $COLLISION_TIMEOUT -t $LOCK_TIMEOUT -m $MONITOR_INTERVAL -u $rscname $device
+ rc=$?
+ if [ $rc -ne 0 ]; then
+ return $rc
+ fi
+ sleep 4
+ get_status $rscname
+ if [ $? -eq 0 ]; then
+ return 0
+ fi
+ return 1
+}
+
+# release has to success
+release_lock(){
+ local rscname=$1
+
+ ## If the lock is already released
+ get_status $rscname
+ if [ $? -ne 0 ]; then
+ return 0
+ fi
+
+ pid=`/usr/bin/pgrep -f "$SFEX_DAEMON .* ${rscname} "`
+ /bin/kill $pid
+
+ count=0
+ while [ $count -lt 10 ]
+ do
+ get_status $rscname
+ if [ $? -eq 1 ]; then
+ return 0
+ fi
+ count=`expr $count + 1`
+ sleep 1
+ done
+
+ /bin/kill -9 $pid
+ while :
+ do
+ get_status $rscname
+ if [ $? -eq 1 ]; then
+ break;
+ fi
+ sleep 1
+ done
+
+ return 0
+}
+
+mode="status"
+
+while getopts ":lusn:i:p:x:" opt; do
+case $opt in
+l )
+mode="lock"
+;;
+u )
+mode="unlock"
+;;
+s )
+mode="status"
+;;
+n )
+vm_name=$OPTARG
+;;
+i )
+vm_uuid=$OPTARG
+;;
+p )
+vm_host=$OPTARG
+;;
+x )
+vm_sfex_device=$OPTARG
+;;
+\? )
+usage
+;;
+esac
+done
+
+shift $(($OPTIND - 1))
+[ -z $vm_uuid ] && usage
+[ -z $vm_sfex_device ] && usage
+
+case $mode in
+lock )
+ (
+ flock -x 200
+ acquire_lock $vm_uuid $vm_sfex_device
+ rc=$?
+ flock -u 200
+ exit $rc
+ ) 200>$LOCAL_LOCK_FILE-$vm_uuid
+;;
+unlock )
+ (
+ flock -x 200
+ release_lock $vm_uuid
+ rc=$?
+ flock -u 200
+ exit $rc
+ ) 200>$LOCAL_LOCK_FILE-$vm_uuid
+;;
+status )
+ get_lock_host $vm_uuid $vm_sfex_device
+;;
+esac
+
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -4559,8 +4559,14 @@ class XendDomainInfo:
# Return name of host contained in lock file.
def get_lock_host(self, path):
- fin = os.popen(xoptions.get_xend_domain_lock_utility() + \
- ' -s ' + path, 'r')
+ lock_cmd = '%s -s -i %s ' % \
+ (xoptions.get_xend_domain_lock_utility(), \
+ self.info['uuid'])
+ lock_dev = xoptions.get_xend_domain_lock_device()
+ if lock_dev:
+ lock_cmd += '-x %d ' % lock_dev
+ lock_cmd += path
+ fin = os.popen(lock_cmd, 'r')
hostname = "unknown"
try:
@@ -4582,6 +4588,16 @@ class XendDomainInfo:
path = xoptions.get_xend_domain_lock_path()
path = os.path.join(path, self.get_uuid())
+ lock_cmd = '%s -l -p %s -n %s -i %s ' % \
+ (xoptions.get_xend_domain_lock_utility(), \
+ XendNode.instance().get_name(), \
+ self.info['name_label'], \
+ self.info['uuid'])
+ lock_dev = xoptions.get_xend_domain_lock_device()
+ if lock_dev:
+ lock_cmd += '-x %d ' % lock_dev
+ lock_cmd += path
+
try:
if not os.path.exists(path):
mkdir.parents(path, stat.S_IRWXU)
@@ -4589,12 +4605,7 @@ class XendDomainInfo:
log.exception("%s could not be created." % path)
raise XendError("%s could not be created." % path)
- status = os.system('%s -l -p %s -n %s -i %s %s' % \
- (xoptions.get_xend_domain_lock_utility(), \
- XendNode.instance().get_name(), \
- self.info['name_label'], \
- self.info['uuid'], \
- path))
+ status = os.system(lock_cmd) >> 8
if status != 0:
log.debug("Failed to aqcuire lock: status = %d" % status)
raise XendError("The VM is locked and appears to be running on host %s." % self.get_lock_host(path))
@@ -4611,12 +4622,18 @@ class XendDomainInfo:
path = xoptions.get_xend_domain_lock_path()
path = os.path.join(path, self.get_uuid())
- status = os.system('%s -u -p %s -n %s -i %s %s' % \
- (xoptions.get_xend_domain_lock_utility(), \
- XendNode.instance().get_name(), \
- dom_name, \
- self.info['uuid'], \
- path))
+
+ lock_cmd = '%s -u -p %s -n %s -i %s ' % \
+ (xoptions.get_xend_domain_lock_utility(), \
+ XendNode.instance().get_name(), \
+ dom_name, \
+ self.info['uuid'])
+ lock_dev = xoptions.get_xend_domain_lock_device()
+ if lock_dev:
+ lock_cmd += '-x %d ' % lock_dev
+ lock_cmd += path
+
+ status = os.system(lock_cmd) >> 8
if status != 0:
log.exception("Failed to release lock: status = %s" % status)
try:
Index: xen-4.4.0-testing/tools/python/xen/xend/XendNode.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendNode.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendNode.py
@@ -162,6 +162,7 @@ class XendNode:
self._init_cpu_pools()
+ self._init_lock_devices()
def _init_networks(self):
# Initialise networks
@@ -382,6 +383,17 @@ class XendNode:
XendCPUPool.recreate_active_pools()
+ def _init_lock_devices(self):
+ if xendoptions().get_xend_domain_lock():
+ if xendoptions().get_xend_domain_lock_utility().endswith("domain-lock-sfex"):
+ lock_device = xendoptions().get_xend_domain_lock_device()
+ if not lock_device:
+ raise XendError("The block device for sfex is not properly configured")
+ status = os.system("lvchange -ay %s" % lock_device) >> 8
+ if status != 0:
+ raise XendError("The block device for sfex could not be initialized")
+
+
def add_network(self, interface):
# TODO
log.debug("add_network(): Not implemented.")
Index: xen-4.4.0-testing/tools/python/xen/xend/XendOptions.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendOptions.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendOptions.py
@@ -164,6 +164,9 @@ class XendOptions:
"""Default script to acquire/release domain lock"""
xend_domain_lock_utility = auxbin.scripts_dir() + "/domain-lock"
+ """Default block device for lock service"""
+ xend_domain_lock_device = ""
+
def __init__(self):
self.configure()
@@ -430,6 +433,8 @@ class XendOptions:
else:
return self.xend_domain_lock_utility
+ def get_xend_domain_lock_device(self):
+ return self.get_config_string('xend-domain-lock-device', self.xend_domain_lock_device)
def get_vnc_tls(self):
return self.get_config_string('vnc-tls', self.xend_vnc_tls)
++++++ xend-domain-lock.patch ++++++
---
tools/examples/xend-config.sxp | 59 ++++++++++++++++++++++
tools/hotplug/Linux/Makefile | 1
tools/hotplug/Linux/domain-lock | 83 ++++++++++++++++++++++++++++++++
tools/hotplug/Linux/vm-monitor | 41 +++++++++++++++
tools/python/xen/xend/XendCheckpoint.py | 9 +++
tools/python/xen/xend/XendDomainInfo.py | 74 ++++++++++++++++++++++++++++
tools/python/xen/xend/XendOptions.py | 29 +++++++++++
7 files changed, 296 insertions(+)
Index: xen-4.4.0-testing/tools/examples/xend-config.sxp
===================================================================
--- xen-4.4.0-testing.orig/tools/examples/xend-config.sxp
+++ xen-4.4.0-testing/tools/examples/xend-config.sxp
@@ -324,6 +324,65 @@
# device assignment could really work properly even after we do this.
#(pci-passthrough-strict-check yes)
+# Domain Locking
+# In a multihost environment, domain locking provides a simple mechanism that
+# prevents simultaneously running a domain on more than one host.
+#
+# If enabled, xend will execute a external lock utility (defined below)
+# on each domain start and stop event. Disabled by default. Set to yes
+# to enable domain locking.
+#
+#(xend-domain-lock no)
+
+# Path where domain lock is stored if xend-domain-lock is enabled.
+# Note: This path must be accessible to all VM Servers participating
+# in domain locking, e.g. by specifying a shared mount point.
+# Lock is placed in /<xend-domain-lock-path>/<domain-uuid>.
+# Default is /var/lib/xen/images/vm_locks/
+#
+#(xend-domain-lock-path /var/lib/images/vm_locks)
+
+# External locking utility called by xend for acquiring/releasing
+# domain lock. By default /etc/xen/scripts/domain-lock will be used
+# if xend-domain-lock is set to yes. Set to path of custom locking
+# utility to override the default.
+#
+# Synopsis of lock-util:
+# lock-util [-l|-u] -n <vm name> -i <vm uuid> -p <physical host> path"
+# -l Acquire (create) lock
+# -u Remove lock
+# -n vm-name Name of domain
+# -i vm-id Id or UUID of domain
+# -p phy-host Name of physical host (dom0)
+# path /<xend-domain-lock-path>/<vm-uuid>
+# Return 0 on success, non-zero on error.
+#
+# lock-util [-s] path"
+# -s Lock status. If lock is acquired, print any contents
+# on stdout and return 0. Return non-zero if lock is
+# available.
+# path /<xend-domain-lock-path>/<vm-uuid>
+# If lock is acquired, print any contents on stdout and return 0.
+# Return non-zero if lock is available.
+#
+# Default lock-util behavior:
+# On domain start event, domain-lock will create and flock(1)
+# /<xend-domain-lock-path>/<vm-uuid>/lock. Every two seconds it
+# will write <vm-name>, <vm-id>, <vm-host>, and <tick> to the lock.
+# <tick> is running counter.
+# On domain stop event, domain-lock will unlock and remove
+# /<xend-domain-lock-path>/<vm-uuid>/lock.
+#
+# Note: If xend-domain-lock-path is a cluster-unaware file system,
+# administrator intervention may be required to remove stale
+# locks. Consider two hosts using NFS for xend-domain-lock-path
+# when HostA, running vm1, crashes. HostB could not acquire a
+# lock for vm1 since the NFS server holds an exclusive lock
+# acquired by HostA. The lock file must be manually removed
+# before starting vm1 on HostB.
+#
+#(xend-domain-lock-utility domain-lock)
+
# If we have a very big scsi device configuration, start of xend is slow,
# because xend scans all the device paths to build its internal PSCSI device
# list. If we need only a few devices for assigning to a guest, we can reduce
Index: xen-4.4.0-testing/tools/hotplug/Linux/Makefile
===================================================================
--- xen-4.4.0-testing.orig/tools/hotplug/Linux/Makefile
+++ xen-4.4.0-testing/tools/hotplug/Linux/Makefile
@@ -23,6 +23,7 @@ XEN_SCRIPTS += xen-hotplug-cleanup
XEN_SCRIPTS += external-device-migrate
XEN_SCRIPTS += vscsi
XEN_SCRIPTS += block-iscsi
+XEN_SCRIPTS += domain-lock vm-monitor
XEN_SCRIPTS += $(XEN_SCRIPTS-y)
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
Index: xen-4.4.0-testing/tools/hotplug/Linux/domain-lock
===================================================================
--- /dev/null
+++ xen-4.4.0-testing/tools/hotplug/Linux/domain-lock
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+basedir=$(dirname "$0")
+
+usage() {
+ echo "usage: domain-lock [-l|-u] -n <vm name> -i <vm uuid> -p <physical host> path"
+ echo "usage: domain-lock [-s] path"
+ echo ""
+ echo "-l lock"
+ echo "-u unlock"
+ echo "-s status (default)"
+ echo "-n Virtual Machine name"
+ echo "-i Virtual Machine Id or UUID"
+ echo "-p Virtual Machine Server (physical host) name"
+ echo "path A per-VM, unique location where external lock will be managed"
+ exit 1
+}
+
+remove_lock(){
+ local path=$1/lock
+ local name=$2
+
+ pid=`ps -efwww | grep vm-monitor | grep $name | awk '{print $2}'`
+ if [ -n "$pid" ]; then
+ kill $pid
+ rm -f $path
+ fi
+}
+
+get_status(){
+ local path=$1/lock
+ [ -f $path ] || exit 1
+
+ rc=`flock -xn $path /bin/true`
+ cat $path
+ exit $rc
+}
+
+mode="status"
+
+while getopts ":lusn:i:p:" opt; do
+ case $opt in
+ l )
+ mode="lock"
+ ;;
+ u )
+ mode="unlock"
+ ;;
+ s )
+ mode="status"
+ ;;
+ p )
+ vm_host=$OPTARG
+ ;;
+ n )
+ vm_name=$OPTARG
+ ;;
+ i )
+ vm_uuid=$OPTARG
+ ;;
+ \? )
+ usage
+ ;;
+ esac
+done
+
+shift $(($OPTIND - 1))
+vm_path=$1
+
+case $mode in
+ lock )
+ [ -z "$vm_path" ] || [ -z "$vm_name" ] || [ -z "$vm_uuid" ] || [ -z "$vm_host" ] && usage
+ $basedir/set-lock $vm_path $vm_name $vm_uuid $vm_host
+ ;;
+ unlock )
+ [ -z "$vm_path" ] || [ -z "$vm_name" ] || [ -z "$vm_uuid" ] || [ -z "$vm_host" ] && usage
+ remove_lock $vm_path $vm_name $vm_uuid $vm_host
+ ;;
+ status )
+ [ -z "$vm_path" ] && usage
+ get_status $vm_path
+ ;;
+esac
Index: xen-4.4.0-testing/tools/hotplug/Linux/vm-monitor
===================================================================
--- /dev/null
+++ xen-4.4.0-testing/tools/hotplug/Linux/vm-monitor
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+basedir=$(dirname "$0")
+HA_TICK=2
+
+monitor() {
+ local path=$1
+ local name=$2
+ local uuid=$3
+ local host=$4
+ local count=0
+ path=$path/lock
+
+ while :
+ do
+ echo "name=$name uuid=$uuid host=$host count=$count" > $path
+ count=$(($count+1))
+ sleep $HA_TICK
+ done&
+}
+
+create_lock() {
+ local path=$1/lock
+ local rc=0
+
+ [ -f $path ] || touch $path
+ flock -x -w $HA_TICK $path $basedir/vm-monitor $*
+ rc=$?
+ if [ $rc -eq 1 ]; then
+ echo `cat $path`
+ exit 1
+ else
+ exit $rc
+ fi
+}
+
+if [ $0 = "$basedir/set-lock" ]; then
+ create_lock $*
+elif [ $0 = "$basedir/vm-monitor" ]; then
+ monitor $*
+fi
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -141,6 +141,11 @@ def save(fd, dominfo, network, live, dst
]
log.debug("[xc_save]: %s", string.join(cmd))
+ # It is safe to release the domain lock at this point if not
+ # checkpointing
+ if checkpoint == False:
+ dominfo.release_running_lock(domain_name)
+
def saveInputHandler(line, tochild):
log.debug("In saveInputHandler %s", line)
if line == "suspend":
@@ -205,6 +210,9 @@ def save(fd, dominfo, network, live, dst
log.exception("Save failed on domain %s (%s) - resuming.", domain_name,
dominfo.getDomid())
dominfo.resumeDomain()
+ # Reacquire the domain lock
+ if checkpoint == False:
+ dominfo.acquire_running_lock()
try:
dominfo.setName(domain_name)
@@ -371,6 +379,7 @@ def restore(xd, fd, dominfo = None, paus
if not paused:
dominfo.unpause()
+ dominfo.acquire_running_lock()
return dominfo
except Exception, exn:
dominfo.destroy()
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -498,6 +498,7 @@ class XendDomainInfo:
if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, XEN_API_VM_POWER_STATE_SUSPENDED, XEN_API_VM_POWER_STATE_CRASHED):
try:
prepare_domain_pci_devices(self.info);
+ self.acquire_running_lock();
XendTask.log_progress(0, 30, self._constructDomain)
XendTask.log_progress(31, 60, self._initDomain)
@@ -3071,6 +3072,11 @@ class XendDomainInfo:
self._stateSet(DOM_STATE_HALTED)
self.domid = None # Do not push into _stateSet()!
+
+ try:
+ self.release_running_lock()
+ except:
+ log.exception("Failed to release domain lock.")
finally:
self.refresh_shutdown_lock.release()
@@ -4551,6 +4557,74 @@ class XendDomainInfo:
def has_device(self, dev_class, dev_uuid):
return (dev_uuid in self.info['%s_refs' % dev_class.lower()])
+ # Return name of host contained in lock file.
+ def get_lock_host(self, path):
+ fin = os.popen(xoptions.get_xend_domain_lock_utility() + \
+ ' -s ' + path, 'r')
+ hostname = "unknown"
+
+ try:
+ tokens = fin.readline().split()
+ for token in tokens:
+ item = token.split('=')
+ if item[0] == 'host':
+ hostname = item[1]
+ return hostname
+ finally:
+ fin.close()
+
+ # Acquire a lock for the domain. No-op if domain locking is turned off.
+ def acquire_running_lock(self):
+ if not xoptions.get_xend_domain_lock():
+ return
+
+ log.debug("Acquiring lock for domain %s" % self.info['name_label'])
+ path = xoptions.get_xend_domain_lock_path()
+ path = os.path.join(path, self.get_uuid())
+
+ try:
+ if not os.path.exists(path):
+ mkdir.parents(path, stat.S_IRWXU)
+ except:
+ log.exception("%s could not be created." % path)
+ raise XendError("%s could not be created." % path)
+
+ status = os.system('%s -l -p %s -n %s -i %s %s' % \
+ (xoptions.get_xend_domain_lock_utility(), \
+ XendNode.instance().get_name(), \
+ self.info['name_label'], \
+ self.info['uuid'], \
+ path))
+ if status != 0:
+ log.debug("Failed to aqcuire lock: status = %d" % status)
+ raise XendError("The VM is locked and appears to be running on host %s." % self.get_lock_host(path))
+
+ # Release lock for domain. No-op if domain locking is turned off.
+ def release_running_lock(self, name = None):
+ if not xoptions.get_xend_domain_lock():
+ return
+
+ dom_name = self.info['name_label']
+ if name:
+ dom_name = name
+ log.debug("Releasing lock for domain %s" % dom_name)
+
+ path = xoptions.get_xend_domain_lock_path()
+ path = os.path.join(path, self.get_uuid())
+ status = os.system('%s -u -p %s -n %s -i %s %s' % \
+ (xoptions.get_xend_domain_lock_utility(), \
+ XendNode.instance().get_name(), \
+ dom_name, \
+ self.info['uuid'], \
+ path))
+ if status != 0:
+ log.exception("Failed to release lock: status = %s" % status)
+ try:
+ if len(os.listdir(path)) == 0:
+ shutil.rmtree(path)
+ except:
+ log.exception("Failed to remove unmanaged directory %s." % path)
+
def __str__(self):
return '<domain id=%s name=%s memory=%s state=%s>' % \
(str(self.domid), self.info['name_label'],
Index: xen-4.4.0-testing/tools/python/xen/xend/XendOptions.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendOptions.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendOptions.py
@@ -154,6 +154,17 @@ class XendOptions:
use loose check automatically if necessary."""
pci_dev_assign_strict_check_default = True
+ """Default for the flag indicating whether xend should create
+ a lock file for domains when they are started."""
+ xend_domain_lock = 'no'
+
+ """Default domain lock storage path."""
+ xend_domain_lock_path_default = '/var/lib/xen/images/vm_locks'
+
+ """Default script to acquire/release domain lock"""
+ xend_domain_lock_utility = auxbin.scripts_dir() + "/domain-lock"
+
+
def __init__(self):
self.configure()
@@ -401,6 +412,24 @@ class XendOptions:
else:
return None
+ def get_xend_domain_lock(self):
+ """Get the flag indicating whether xend should create a lock file
+ for domains when they are started."""
+ return self.get_config_bool("xend-domain-lock", self.xend_domain_lock)
+
+ def get_xend_domain_lock_path(self):
+ """ Get the path for domain lock storage
+ """
+ return self.get_config_string("xend-domain-lock-path", self.xend_domain_lock_path_default)
+
+ def get_xend_domain_lock_utility(self):
+ s = self.get_config_string('xend-domain-lock-utility')
+
+ if s:
+ return os.path.join(auxbin.scripts_dir(), s)
+ else:
+ return self.xend_domain_lock_utility
+
def get_vnc_tls(self):
return self.get_config_string('vnc-tls', self.xend_vnc_tls)
++++++ xend-domu-usb-controller.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
@@ -1865,7 +1865,14 @@ class XendConfig(dict):
ports = sxp.child(dev_sxp, 'port')
for port in ports[1:]:
try:
- num, bus = port
+ # When ['port' ['1','']] is saved into sxp file, it will become (port (1 ))
+ # If using this sxp file, here variable "port" will be port=1,
+ # we should process it, otherwise, it will report error.
+ if len(port) == 1:
+ num = port[0]
+ bus = ""
+ else:
+ num, bus = port
dev_config['port-%i' % int(num)] = str(bus)
except TypeError:
pass
++++++ xend-fix-sendkey.patch ++++++
Index: xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/server/SrvDomain.py
+++ xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py
@@ -78,7 +78,7 @@ class SrvDomain(SrvDir):
def op_sysrq(self, _, req):
self.acceptCommand(req)
- return self.dom.send_sysrq(int(req.args['key'][0]))
+ return self.dom.send_sysrq(req.args['key'][0])
def op_wait_for_devices(self, _, req):
self.acceptCommand(req)
++++++ xend-hv_extid_compatibility.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
@@ -161,6 +161,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
'nographic': int,
'nomigrate': int,
'pae' : int,
+ 'extid': int,
'rtc_timeoffset': int,
'parallel': str,
'serial': str,
@@ -522,6 +523,8 @@ class XendConfig(dict):
self['platform']['acpi_firmware'] = ""
if 'timer_mode' not in self['platform']:
self['platform']['timer_mode'] = 1
+ if 'extid' in self['platform'] and int(self['platform']['extid']) == 1:
+ self['platform']['viridian'] = 1
if 'viridian' not in self['platform']:
self['platform']['viridian'] = 0
if 'rtc_timeoffset' not in self['platform']:
Index: xen-4.4.0-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.4.0-testing/tools/python/xen/xend/image.py
@@ -830,6 +830,7 @@ class HVMImageHandler(ImageHandler):
self.apic = int(vmConfig['platform'].get('apic', 0))
self.acpi = int(vmConfig['platform'].get('acpi', 0))
+ self.extid = int(vmConfig['platform'].get('extid', 0))
self.guest_os_type = vmConfig['platform'].get('guest_os_type')
self.memory_sharing = int(vmConfig['memory_sharing'])
try:
Index: xen-4.4.0-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.4.0-testing/tools/python/xen/xm/create.py
@@ -242,6 +242,10 @@ gopts.var('viridian', val='VIRIDIAN',
use="""Expose Viridian interface to x86 HVM guest?
(Default is 0).""")
+gopts.var('extid', val='EXTID',
+ fn=set_int, default=0,
+ use="Specify extention ID for a HVM domain.")
+
gopts.var('acpi', val='ACPI',
fn=set_int, default=1,
use="Disable or enable ACPI of HVM domain.")
@@ -1071,7 +1075,7 @@ def configure_hvm(config_image, vals):
'timer_mode',
'usb', 'usbdevice',
'vcpus', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten',
- 'vncunused', 'viridian', 'vpt_align',
+ 'vncunused', 'vpt_align',
'watchdog', 'watchdog_action',
'xauthority', 'xen_extended_power_mgmt', 'xen_platform_pci',
'memory_sharing' ]
@@ -1081,6 +1085,10 @@ def configure_hvm(config_image, vals):
config_image.append([a, vals.__dict__[a]])
if vals.vncpasswd is not None:
config_image.append(['vncpasswd', vals.vncpasswd])
+ if vals.extid and vals.extid == 1:
+ config_image.append(['viridian', vals.extid])
+ elif vals.viridian:
+ config_image.append(['viridian', vals.viridian])
def make_config(vals):
++++++ xend-hvm-default-pae.patch ++++++
PAE must be on for 64-on-64 to work at all.
Index: xen-4.2.0-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.2.0-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.2.0-testing/tools/python/xen/xend/image.py
@@ -1038,7 +1038,7 @@ class X86_HVM_ImageHandler(HVMImageHandl
def configure(self, vmConfig):
HVMImageHandler.configure(self, vmConfig)
- self.pae = int(vmConfig['platform'].get('pae', 0))
+ self.pae = int(vmConfig['platform'].get('pae', 1))
self.vramsize = int(vmConfig['platform'].get('videoram',4)) * 1024
def buildDomain(self):
++++++ xend-hvm-firmware-passthrough.patch ++++++
fate#313584: pass bios information to XEN HVM guest
Index: xen-4.4.0-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.4.0-testing/tools/python/xen/xm/create.py
@@ -473,6 +473,14 @@ gopts.var('nfs_root', val="PATH",
fn=set_value, default=None,
use="Set the path of the root NFS directory.")
+gopts.var('smbios_firmware', val='FILE',
+ fn=set_value, default=None,
+ use="Path to a file that contains extra SMBIOS firmware structures.")
+
+gopts.var('acpi_firmware', val='FILE',
+ fn=set_value, default=None,
+ use="Path to a file that contains extra ACPI firmware tables.")
+
gopts.var('device_model', val='FILE',
fn=set_value, default=None,
use="Path to device model program.")
@@ -1048,6 +1056,7 @@ def configure_hvm(config_image, vals):
'boot',
'cpuid', 'cpuid_check',
'device_model', 'display',
+ 'smbios_firmware', 'acpi_firmware',
'fda', 'fdb',
'gfx_passthru', 'guest_os_type',
'hap', 'hpet',
Index: xen-4.4.0-testing/tools/python/xen/xm/xenapi_create.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/xenapi_create.py
+++ xen-4.4.0-testing/tools/python/xen/xm/xenapi_create.py
@@ -1047,6 +1047,8 @@ class sxp2xml:
'apic',
'boot',
'device_model',
+ 'smbios_firmware',
+ 'acpi_firmware',
'loader',
'fda',
'fdb',
Index: xen-4.4.0-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.4.0-testing/tools/python/xen/xend/image.py
@@ -17,7 +17,7 @@
#============================================================================
-import os, os.path, string
+import os, os.path, string, struct, stat
import re
import math
import time
@@ -123,6 +123,8 @@ class ImageHandler:
self.device_model = vmConfig['platform'].get('device_model')
+ self.smbios_firmware =(str(vmConfig['platform'].get('smbios_firmware')))
+ self.acpi_firmware =(str(vmConfig['platform'].get('acpi_firmware')))
self.display = vmConfig['platform'].get('display')
self.xauthority = vmConfig['platform'].get('xauthority')
self.vncconsole = int(vmConfig['platform'].get('vncconsole', 0))
@@ -945,6 +947,38 @@ class HVMImageHandler(ImageHandler):
self.vm.getDomid() ])
return args
+ def _readFirmwareFile(self, filename):
+ # Sanity check
+ if filename is None or filename.strip() == "":
+ size = struct.pack('i', int(0))
+ return size + ""
+
+ log.debug("Reading firmware file %s", filename)
+ # Open
+ try:
+ fd = os.open(filename, os.O_RDONLY)
+ except Exception, e:
+ raise VmError('Unable to open firmware file %s' % filename)
+
+ # Validate file size
+ statinfo = os.fstat(fd)
+ if statinfo.st_size == 0 or statinfo.st_size > sys.maxint:
+ os.close(fd)
+ raise VmError('Firmware file %s is an invalid size' % filename)
+ if not stat.S_ISREG(statinfo.st_mode):
+ os.close(fd)
+ raise VmError('Firmware file %s is an invalid file type' % filename)
+ size = struct.pack('i', statinfo.st_size)
+
+ # Read entire file
+ try:
+ buf = os.read(fd, statinfo.st_size)
+ except Exception, e:
+ os.close(fd)
+ raise VmError('Failed reading firmware file %s' % filename)
+ os.close(fd)
+ return size+buf
+
def buildDomain(self):
store_evtchn = self.vm.getStorePort()
@@ -960,6 +994,8 @@ class HVMImageHandler(ImageHandler):
log.debug("vcpu_avail = %li", self.vm.getVCpuAvail())
log.debug("acpi = %d", self.acpi)
log.debug("apic = %d", self.apic)
+ log.debug("smbios_firmware= %s", self.smbios_firmware)
+ log.debug("acpi_firmware = %s", self.acpi_firmware)
rc = xc.hvm_build(domid = self.vm.getDomid(),
image = self.loader,
@@ -968,7 +1004,9 @@ class HVMImageHandler(ImageHandler):
vcpus = self.vm.getVCpuCount(),
vcpu_avail = self.vm.getVCpuAvail(),
acpi = self.acpi,
- apic = self.apic)
+ apic = self.apic,
+ smbios_firmware= self._readFirmwareFile(self.smbios_firmware),
+ acpi_firmware = self._readFirmwareFile(self.acpi_firmware))
rc['notes'] = { 'SUSPEND_CANCEL': 1 }
rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(),
Index: xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
@@ -147,6 +147,8 @@ XENAPI_PLATFORM_CFG_TYPES = {
'apic': int,
'boot': str,
'device_model': str,
+ 'smbios_firmware': str,
+ 'acpi_firmware': str,
'loader': str,
'display' : str,
'fda': str,
@@ -514,6 +516,10 @@ class XendConfig(dict):
self['platform']['nomigrate'] = 0
if self.is_hvm():
+ if 'smbios_firmware' not in self['platform']:
+ self['platform']['smbios_firmware'] = ""
+ if 'acpi_firmware' not in self['platform']:
+ self['platform']['acpi_firmware'] = ""
if 'timer_mode' not in self['platform']:
self['platform']['timer_mode'] = 1
if 'viridian' not in self['platform']:
Index: xen-4.4.0-testing/tools/python/xen/lowlevel/xc/xc.c
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/lowlevel/xc/xc.c
+++ xen-4.4.0-testing/tools/python/xen/lowlevel/xc/xc.c
@@ -915,18 +915,23 @@ static PyObject *pyxc_hvm_build(XcObject
uint32_t dom;
struct hvm_info_table *va_hvm;
uint8_t *va_map, sum;
- int i;
- char *image;
+ int i, datalen;
+ char *image, *smbios_str, *acpi_str;
int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1;
+ PyObject *acpi_firmware = NULL;
+ PyObject *smbios_firmware = NULL;
PyObject *vcpu_avail_handle = NULL;
uint8_t vcpu_avail[(HVM_MAX_VCPUS + 7)/8];
+ struct xc_hvm_build_args hvm_args = {};
static char *kwd_list[] = { "domid",
"memsize", "image", "target", "vcpus",
- "vcpu_avail", "acpi", "apic", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiOii", kwd_list,
+ "vcpu_avail", "acpi", "apic",
+ "smbios_firmware", "acpi_firmware", NULL };
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiOiiOO", kwd_list,
&dom, &memsize, &image, &target, &vcpus,
- &vcpu_avail_handle, &acpi, &apic) )
+ &vcpu_avail_handle, &acpi,
+ &apic, &smbios_firmware, &acpi_firmware) )
return NULL;
memset(vcpu_avail, 0, sizeof(vcpu_avail));
@@ -957,8 +962,38 @@ static PyObject *pyxc_hvm_build(XcObject
if ( target == -1 )
target = memsize;
- if ( xc_hvm_build_target_mem(self->xc_handle, dom, memsize,
- target, image) != 0 )
+ memset(&hvm_args, 0, sizeof(struct xc_hvm_build_args));
+ hvm_args.mem_size = (uint64_t)memsize << 20;
+ hvm_args.mem_target = (uint64_t)target << 20;
+ hvm_args.image_file_name = image;
+
+ if ( PyString_Check(smbios_firmware ) )
+ {
+ smbios_str = PyString_AsString(smbios_firmware);
+ if ( smbios_str )
+ {
+ datalen = *(int *)smbios_str;
+ if ( datalen ) {
+ hvm_args.smbios_module.data = &((uint8_t *)smbios_str)[4];
+ hvm_args.smbios_module.length = (uint32_t)datalen;
+ }
+ }
+ }
+
+ if ( PyString_Check(acpi_firmware ) )
+ {
+ acpi_str = PyString_AsString(acpi_firmware);
+ if (acpi_str)
+ {
+ datalen = *(int *)acpi_str;
+ if ( datalen ) {
+ hvm_args.acpi_module.data = &((uint8_t *)acpi_str)[4];
+ hvm_args.acpi_module.length = (uint32_t)datalen;
+ }
+ }
+ }
+
+ if ( xc_hvm_build(self->xc_handle, dom, &hvm_args) != 0 )
return pyxc_error_to_exception(self->xc_handle);
/* Fix up the HVM info table. */
Index: xen-4.4.0-testing/docs/man/xmdomain.cfg.pod.5
===================================================================
--- xen-4.4.0-testing.orig/docs/man/xmdomain.cfg.pod.5
+++ xen-4.4.0-testing/docs/man/xmdomain.cfg.pod.5
@@ -243,6 +243,25 @@ this the xen kernel must be compiled wit
This defaults to 1, meaning running the domain as a UP.
+=item B
+
+Specify a path to a file that contains extra ACPI firmware tables to pass in to
+a guest. The file can contain several tables in their binary AML form
+concatenated together. Each table self describes its length so no additional
+information is needed. These tables will be added to the ACPI table set in the
+guest. Note that existing tables cannot be overridden by this feature. For
+example this cannot be used to override tables like DSDT, FADT, etc.
+
+=item B
+
+Specify a path to a file that contains extra SMBIOS firmware structures to pass
+in to a guest. The file can contain a set DMTF predefined structures which will
+override the internal defaults. Not all predefined structures can be overridden,
+only the following types: 0, 1, 2, 3, 11, 22, 39. The file can also contain any
+number of vendor defined SMBIOS structures (type 128 - 255). Since SMBIOS
+structures do not present their overall size, each entry in the file must be
+preceded by a 32b integer indicating the size of the next structure.
+
=back
=head1 DOMAIN SHUTDOWN OPTIONS
Index: xen-4.4.0-testing/tools/python/README.sxpcfg
===================================================================
--- xen-4.4.0-testing.orig/tools/python/README.sxpcfg
+++ xen-4.4.0-testing/tools/python/README.sxpcfg
@@ -51,6 +51,8 @@ image
- vncunused
(HVM)
- device_model
+ - smbios_firmware
+ - acpi_firmware
- display
- xauthority
- vncconsole
Index: xen-4.4.0-testing/tools/python/README.XendConfig
===================================================================
--- xen-4.4.0-testing.orig/tools/python/README.XendConfig
+++ xen-4.4.0-testing/tools/python/README.XendConfig
@@ -118,6 +118,8 @@ otherConfig
image.vncdisplay
image.vncunused
image.hvm.device_model
+ image.hvm.smbios_firmware
+ image.hvm.apci_firmware
image.hvm.display
image.hvm.xauthority
image.hvm.vncconsole
++++++ xend-managed-pci-device.patch ++++++
pci passthrough: handle managed pci devices
Handle managed pci devices for libvirt usage. If a pci device is set
"managed=1", it will be made assignable (unbound from original driver and bind
to pcistub driver) before vm start and reattach to original driver after vm
shut off.
FATE#313570
Note: This patch was rejected upstream since xend is deprecated. See the
following thread for details
http://lists.xen.org/archives/html/xen-devel/2013-01/msg01145.html
Signed-off-by: Chunyan Liu
Index: xen-4.4.0-testing/tools/python/xen/util/pci.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/util/pci.py
+++ xen-4.4.0-testing/tools/python/xen/util/pci.py
@@ -20,6 +20,8 @@ from xen.xend import sxp
from xen.xend.XendConstants import AUTO_PHP_SLOT
from xen.xend.XendSXPDev import dev_dict_to_sxp
from xen.xend.XendLogging import log
+from xen.xend.xenstore.xstransact import xstransact
+from xen.xend.XendError import XendError
# for 2.3 compatibility
try:
@@ -27,9 +29,11 @@ try:
except NameError:
from sets import Set as set
+XS_PCIBACK_PATH = '/xm/pciback'
PROC_PCI_PATH = '/proc/bus/pci/devices'
PROC_PCI_NUM_RESOURCES = 7
+SYSFS_PCI_DRVS_PATH = 'bus/pci/drivers'
SYSFS_PCI_DEVS_PATH = '/bus/pci/devices'
SYSFS_PCI_DEV_RESOURCE_PATH = '/resource'
SYSFS_PCI_DEV_CONFIG_PATH = '/config'
@@ -161,7 +165,7 @@ def PCI_BDF(domain, bus, slot, func):
def check_pci_opts(opts):
def f((k, v)):
- if k not in ['msitranslate', 'power_mgmt'] or \
+ if k not in ['msitranslate', 'power_mgmt', 'managed'] or \
not v.lower() in ['0', '1', 'yes', 'no']:
raise PciDeviceParseError('Invalid pci option %s=%s: ' % (k, v))
@@ -427,6 +431,9 @@ def __pci_dict_to_fmt_str(fmt, dev):
def pci_dict_to_bdf_str(dev):
return __pci_dict_to_fmt_str('%04x:%02x:%02x.%01x', dev)
+def pci_dict_to_xs_bdf_str(dev):
+ return __pci_dict_to_fmt_str('%04x-%02x-%02x-%01x', dev)
+
def pci_dict_to_xc_str(dev):
return __pci_dict_to_fmt_str('0x%x, 0x%x, 0x%x, 0x%x', dev)
@@ -561,6 +568,115 @@ def find_all_assignable_devices():
dev_list = dev_list + [dev]
return dev_list
+def pci_assignable_add(dev):
+ '''detach pci device from driver that we need to unbind from and rebind
+ to pciback driver, then it can be assigned to guest.
+ '''
+ sysfs_mnt = find_sysfs_mnt()
+ pcidev_path = sysfs_mnt + SYSFS_PCI_DEVS_PATH
+ pciback_path = sysfs_mnt + SYSFS_PCIBACK_PATH
+
+ # See if the device exists
+ pci_bdf = pci_dict_to_bdf_str(dev)
+ path = pcidev_path + '/' + pci_bdf
+ if not os.path.exists(path):
+ log.debug("Pci device %s doesn't exist" % pci_bdf)
+ return -1
+
+ # Check to see if it's already assigned to pciback
+ path = pciback_path + '/' + pci_bdf
+ if os.path.exists(path):
+ log.debug("Pci device %s is already assigned to pciback" % pci_bdf)
+ return 0
+
+ # Check to see if there's already a driver that we need to unbind from
+ path = pcidev_path + '/' + pci_bdf + '/driver'
+ drv_path = None
+ if os.path.exists(path):
+ drv_path = os.path.realpath(path).replace(" ", "\ ")
+ cmd = 'echo %s > %s/unbind' % (pci_bdf, drv_path)
+ if os.system(cmd):
+ log.debug("Couldn't unbind device")
+ return -1;
+
+ # Store driver_path for rebinding to dom0
+ if drv_path is not None:
+ xs_pci_bdf = pci_dict_to_xs_bdf_str(dev)
+ path = XS_PCIBACK_PATH + '/' + xs_pci_bdf
+ xstransact.Mkdir(path)
+ xstransact.Write(path, 'driver_path', drv_path)
+ else:
+ log.debug("Not bound to a driver, will not be rebound")
+
+ # Bind to pciback
+ try:
+ # Scan through /sys/.../pciback/slots looking for pcidev's BDF
+ slots = os.popen('cat %s/slots' % pciback_path).read()
+ if re.search(pci_bdf, slots) is None:
+ # write bdf to new_slot
+ cmd = 'echo %s > %s/new_slot' % (pci_bdf, pciback_path)
+ if os.system(cmd):
+ raise XendError("Couldn't add device to pciback new_slot")
+
+ # Bind to pciback
+ cmd = 'echo %s > %s/bind' % (pci_bdf, pciback_path)
+ if os.system(cmd):
+ raise XendError("Couldn't bind device to pciback")
+ except XendError:
+ # rebind to original driver
+ if drv_path is not None:
+ log.debug("Rebind to original driver")
+ cmd = 'echo %s > %s/bind' % (pci_bdf, drv_path)
+ if os.system(cmd):
+ log.debug("Failed to rebind")
+ return -1
+
+ return 0
+
+def pci_assignable_remove(dev):
+ '''unbind pci device from pciback, and rebind to host pci driver where it
+ was detached from in pci-assignable-add.
+ '''
+ sysfs_mnt = find_sysfs_mnt()
+ pcidrv_path = sysfs_mnt + SYSFS_PCI_DRVS_PATH
+ pciback_path = sysfs_mnt + SYSFS_PCIBACK_PATH
+ pci_bdf = pci_dict_to_bdf_str(dev)
+
+ # Unbind from pciback
+ path = pciback_path + '/' + pci_bdf
+ if os.path.exists(path):
+ # unbind
+ cmd = 'echo %s > %s/unbind' % (pci_bdf, pciback_path)
+ if os.system(cmd):
+ log.debug("Couldn't unbind device to pciback")
+ return -1
+
+ # remove slots if necessary
+ slots = os.popen('cat %s/slots' % pciback_path).read()
+ if re.search(pci_bdf, slots):
+ # write bdf to remove_slot
+ cmd = 'echo %s > %s/remove_slot' % (pci_bdf, pciback_path)
+ if os.system(cmd):
+ log.debug("Couldn't remove pciback slot")
+ return -1
+ else:
+ log.debug("Not bound to pciback")
+
+ # Rebind if necessary
+ xs_pci_bdf = pci_dict_to_xs_bdf_str(dev)
+ path = XS_PCIBACK_PATH + '/' + xs_pci_bdf
+ drv_path = xstransact.Read(path, 'driver_path')
+ if drv_path:
+ cmd = 'echo %s > %s/bind' % (pci_bdf, drv_path)
+ if os.system(cmd):
+ log.debug("Couldn't rebind to driver %s" % drv_path)
+ return -1
+ xstransact.Remove(path)
+ else:
+ log.debug("Counldn't find path for original driver. Not rebinding")
+
+ return 0
+
def transform_list(target, src):
''' src: its element is pci string (Format: xxxx:xx:xx.x).
target: its element is pci string, or a list of pci string.
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -305,7 +305,8 @@ def dom_get(dom):
return None
from xen.xend.server.pciif import parse_pci_name, PciDevice,\
- get_assigned_pci_devices, get_all_assigned_pci_devices
+ get_assigned_pci_devices, get_all_assigned_pci_devices,\
+ prepare_host_pci_devices, reattach_host_pci_devices
def do_FLR(domid, is_hvm):
@@ -319,6 +320,20 @@ def do_FLR(domid, is_hvm):
"parse it's resources - "+str(e))
dev.do_FLR(is_hvm, xoptions.get_pci_dev_assign_strict_check())
+def prepare_domain_pci_devices(domconfig):
+ ordered_refs = domconfig.ordered_device_refs()
+ for dev_uuid in ordered_refs:
+ devclass, devconfig = domconfig['devices'][dev_uuid]
+ if devclass == 'pci':
+ prepare_host_pci_devices(devconfig)
+
+def reattach_domain_pci_devices(domconfig):
+ ordered_refs = domconfig.ordered_device_refs()
+ for dev_uuid in ordered_refs:
+ devclass, devconfig = domconfig['devices'][dev_uuid]
+ if devclass == 'pci':
+ reattach_host_pci_devices(devconfig)
+
class XendDomainInfo:
"""An object represents a domain.
@@ -472,6 +487,7 @@ class XendDomainInfo:
if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, XEN_API_VM_POWER_STATE_SUSPENDED, XEN_API_VM_POWER_STATE_CRASHED):
try:
+ prepare_domain_pci_devices(self.info);
XendTask.log_progress(0, 30, self._constructDomain)
XendTask.log_progress(31, 60, self._initDomain)
@@ -498,6 +514,7 @@ class XendDomainInfo:
state = self._stateGet()
if state in (DOM_STATE_SUSPENDED, DOM_STATE_HALTED):
try:
+ prepare_domain_pci_devices(self.info)
self._constructDomain()
try:
@@ -714,6 +731,8 @@ class XendDomainInfo:
the device.
"""
+ if self.domid is None:
+ return
self.iommu_check_pod_mode()
# Test whether the devices can be assigned
@@ -853,6 +872,9 @@ class XendDomainInfo:
if self.domid is not None:
try:
+ if dev_type == 'pci':
+ prepare_host_pci_devices(dev_config_dict)
+
dev_config_dict['devid'] = devid = \
self._createDevice(dev_type, dev_config_dict)
if dev_type == 'tap2':
@@ -866,6 +888,7 @@ class XendDomainInfo:
if dev_type == 'pci':
for dev in dev_config_dict['devs']:
XendAPIStore.deregister(dev['uuid'], 'DPCI')
+ reattach_host_pci_devices(dev_config_dict)
elif dev_type == 'vscsi':
for dev in dev_config_dict['devs']:
XendAPIStore.deregister(dev['uuid'], 'DSCSI')
@@ -910,6 +933,10 @@ class XendDomainInfo:
dev_config = pci_convert_sxp_to_dict(dev_sxp)
dev = dev_config['devs'][0]
+ # For attach only. For boot, prepare work has been done already in earlier stage.
+ if self.domid is not None and pci_state == 'Initialising' and pci_sub_state != 'Booting':
+ prepare_host_pci_devices(dev_config)
+
stubdomid = self.getStubdomDomid()
# Do HVM specific processing
if self.info.is_hvm():
@@ -986,6 +1013,9 @@ class XendDomainInfo:
new_dev_sxp = dev_control.configuration(devid)
self.info.device_update(dev_uuid, new_dev_sxp)
+ if pci_state == 'Closing':
+ reattach_host_pci_devices(dev_config)
+
# If there is no device left, destroy pci and remove config.
if num_devs == 0:
if self.info.is_hvm():
@@ -3175,6 +3205,7 @@ class XendDomainInfo:
log.debug("%s KiB need to add to Memory pool" %self.alloc_mem)
MemoryPool.instance().increase_memory(self.alloc_mem)
+ reattach_domain_pci_devices(self.info)
self._cleanup_phantom_devs(paths)
self._cleanupVm()
Index: xen-4.4.0-testing/tools/python/xen/xend/server/pciif.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/server/pciif.py
+++ xen-4.4.0-testing/tools/python/xen/xend/server/pciif.py
@@ -86,6 +86,48 @@ def get_all_assigned_pci_devices(domid =
pci_str_list = pci_str_list + get_assigned_pci_devices(int(d))
return pci_str_list
+def reattach_host_pci_devices(devconfig):
+ pci_dev_list = devconfig.get('devs', [])
+ for pci_dev in pci_dev_list:
+ managed = 0
+ pci_opts_config = pci_dev.get('opts', [])
+ for opt in pci_opts_config:
+ if opt[0] == 'managed':
+ managed = opt[1]
+ if managed:
+ if pci_assignable_remove(pci_dev) != 0:
+ raise VmError('pci_assignable_remove failed')
+
+def detach_host_pci_devices(devconfig):
+ pci_dev_list = devconfig.get('devs', [])
+ reattach = 0
+ for pci_dev in pci_dev_list:
+ managed = 0
+ pci_opts_config = pci_dev.get('opts', [])
+ for opt in pci_opts_config:
+ if opt[0] == 'managed':
+ managed = opt[1]
+ if managed:
+ if pci_assignable_add(pci_dev) != 0:
+ log.debug('pci_assignable_add failed')
+ reattach = 1
+ break
+
+ if reattach:
+ reattach_host_pci_devices(devconfig)
+ raise VmError('detach_host_pci_devices failed')
+
+def prepare_host_pci_devices(devconfig):
+ # Test whether the device used by other domain
+ pci_dev_list = devconfig.get('devs', [])
+ for pci_dev in pci_dev_list:
+ pci_name = pci_dict_to_bdf_str(pci_dev)
+ if pci_name in get_all_assigned_pci_devices():
+ raise VmError("failed to assign device %s that has"
+ " already been assigned to other domain." % pci_name)
+ # Detach 'managed' devices
+ detach_host_pci_devices(devconfig)
+
class PciController(DevController):
def __init__(self, vm):
++++++ xend-max-free-mem.patch ++++++
Index: xen-4.4.1-testing/tools/python/xen/xend/XendNode.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/XendNode.py
+++ xen-4.4.1-testing/tools/python/xen/xend/XendNode.py
@@ -949,11 +949,35 @@ class XendNode:
info['cpu_mhz'] = info['cpu_khz'] / 1000
- # physinfo is in KiB, need it in MiB
- info['total_memory'] = info['total_memory'] / 1024
- info['free_memory'] = info['free_memory'] / 1024
+ configured_floor = xendoptions().get_dom0_min_mem() * 1024
+ from xen.xend import balloon
+ try:
+ kernel_floor = balloon.get_dom0_min_target()
+ except:
+ kernel_floor = 0
+ dom0_min_mem = max(configured_floor, kernel_floor)
+ dom0_mem = balloon.get_dom0_current_alloc()
+ extra_mem = 0
+ if dom0_min_mem > 0 and dom0_mem > dom0_min_mem:
+ extra_mem = dom0_mem - dom0_min_mem
+ info['free_memory'] = info['free_memory'] + info['scrub_memory']
+ info['max_free_memory'] = info['free_memory'] + extra_mem
info['free_cpus'] = len(XendCPUPool.unbound_cpus())
+ # Convert KiB to MiB, rounding down to be conservative
+ info['total_memory'] = info['total_memory'] / 1024
+ info['free_memory'] = info['free_memory'] / 1024
+ info['max_free_memory'] = info['max_free_memory'] / 1024
+
+ # FIXME: These are hard-coded to be the inverse of the getXenMemory
+ # functions in image.py. Find a cleaner way.
+ info['max_para_memory'] = info['max_free_memory'] - 4
+ if info['max_para_memory'] < 0:
+ info['max_para_memory'] = 0
+ info['max_hvm_memory'] = int((info['max_free_memory']-12) * (1-2.4/1024))
+ if info['max_hvm_memory'] < 0:
+ info['max_hvm_memory'] = 0
+
ITEM_ORDER = ['nr_cpus',
'nr_nodes',
'cores_per_socket',
@@ -964,6 +988,9 @@ class XendNode:
'total_memory',
'free_memory',
'free_cpus',
+ 'max_free_memory',
+ 'max_para_memory',
+ 'max_hvm_memory',
]
if show_numa != 0:
Index: xen-4.4.1-testing/tools/python/xen/xend/balloon.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/balloon.py
+++ xen-4.4.1-testing/tools/python/xen/xend/balloon.py
@@ -43,6 +43,8 @@ SLEEP_TIME_GROWTH = 0.1
# label actually shown in the PROC_XEN_BALLOON file.
#labels = { 'current' : 'Current allocation',
# 'target' : 'Requested target',
+# 'min-target' : 'Minimum target',
+# 'max-target' : 'Maximum target',
# 'low-balloon' : 'Low-mem balloon',
# 'high-balloon' : 'High-mem balloon',
# 'limit' : 'Xen hard limit' }
@@ -69,6 +71,23 @@ def get_dom0_target_alloc():
raise VmError('Failed to query target memory allocation of dom0.')
return kb
+def get_dom0_min_target():
+ """Returns the minimum amount of memory (in KiB) that dom0 will accept."""
+
+ kb = _get_proc_balloon('min-target')
+ if kb == None:
+ raise VmError('Failed to query minimum target memory allocation of dom0.')
+ return kb
+
+def get_dom0_max_target():
+ """Returns the maximum amount of memory (in KiB) that is potentially
+ visible to dom0."""
+
+ kb = _get_proc_balloon('max-target')
+ if kb == None:
+ raise VmError('Failed to query maximum target memory allocation of dom0.')
+ return kb
+
def free(need_mem, dominfo):
"""Balloon out memory from the privileged domain so that there is the
specified required amount (in KiB) free.
Index: xen-4.4.1-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1477,6 +1477,27 @@ class XendDomainInfo:
self.info['abort_if_busy'] = str(abort_if_busy)
self.info['log_save_progress'] = str(log_save_progress)
+ def capAndSetMemoryTarget(self, target):
+ """Potentially lowers the requested target to the largest possible
+ value (i.e., caps it), and then sets the memory target of this domain
+ to that value.
+ @param target in MiB.
+ """
+ max_target = 0
+ if self.domid == 0:
+ try:
+ from balloon import get_dom0_max_target
+ max_target = get_dom0_max_target() / 1024
+ except:
+ # It's nice to cap the max at sane values, but harmless to set
+ # them high. Carry on.
+ pass
+ if max_target and target > max_target:
+ log.debug("Requested memory target %d MiB; maximum reasonable is %d MiB.",
+ target, max_target)
+ target = max_target
+ self.setMemoryTarget(target)
+
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
Index: xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/server/SrvDomain.py
+++ xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py
@@ -198,7 +198,7 @@ class SrvDomain(SrvDir):
def op_mem_target_set(self, _, req):
- return self.call(self.dom.setMemoryTarget,
+ return self.call(self.dom.capAndSetMemoryTarget,
[['target', 'int']],
req)
Index: xen-4.4.1-testing/tools/python/xen/xend/osdep.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/osdep.py
+++ xen-4.4.1-testing/tools/python/xen/xend/osdep.py
@@ -42,6 +42,8 @@ def _linux_balloon_stat_proc(label):
xend2linux_labels = { 'current' : 'Current allocation',
'target' : 'Requested target',
+ 'min-target' : 'Minimum target',
+ 'max-target' : 'Maximum target',
'low-balloon' : 'Low-mem balloon',
'high-balloon' : 'High-mem balloon',
'limit' : 'Xen hard limit' }
++++++ xend-migration-bridge-check.patch ++++++
bnc#757525
Index: xen-4.2.0-testing/tools/python/xen/xend/server/netif.py
===================================================================
--- xen-4.2.0-testing.orig/tools/python/xen/xend/server/netif.py
+++ xen-4.2.0-testing/tools/python/xen/xend/server/netif.py
@@ -23,6 +23,7 @@
import os
import random
import re
+import commands
from xen.xend import XendOptions, sxp
from xen.xend.server.DevController import DevController
@@ -101,6 +102,14 @@ class NetifController(DevController):
def __init__(self, vm):
DevController.__init__(self, vm)
+ def createDevice(self, config):
+ bridge = config.get('bridge')
+ if bridge is not None:
+ bridge_result = commands.getstatusoutput("/sbin/ifconfig %s" % bridge)
+ if bridge_result[0] != 0:
+ raise VmError('Network bridge does not exist: %s' % bridge)
+ DevController.createDevice(self, config)
+
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
++++++ xend-migration-domname-fix.patch ++++++
setName() writes the new name to xenstore/Dompath too, so that those read
domname from xenstore (like 'virsh list') could get correct value.
2nd hunk prevents writing xenstore if not "checkpoint", otherwise, vm
destroyed but there is still VM entry in xenstore.
Signed-off-by: Chunyan Liu
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1982,6 +1982,8 @@ class XendDomainInfo:
self.info['name_label'] = name
if to_store:
self.storeVm("name", name)
+ if self.dompath:
+ self.storeDom("name", name)
def getName(self):
return self.info['name_label']
Index: xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -190,7 +190,10 @@ def save(fd, dominfo, network, live, dst
dominfo.destroy()
dominfo.testDeviceComplete()
try:
- dominfo.setName(domain_name)
+ if checkpoint:
+ dominfo.setName(domain_name)
+ else:
+ dominfo.setName(domain_name, False)
except VmError:
# Ignore this. The name conflict (hopefully) arises because we
# are doing localhost migration; if we are doing a suspend of a
++++++ xend-minimum-restart-time.patch ++++++
References: bnc#661298
Index: xen-4.2.0-testing/tools/python/xen/xend/XendConstants.py
===================================================================
--- xen-4.2.0-testing.orig/tools/python/xen/xend/XendConstants.py
+++ xen-4.2.0-testing/tools/python/xen/xend/XendConstants.py
@@ -94,7 +94,7 @@ DOM_STATES_OLD = [
SHUTDOWN_TIMEOUT = (60.0 * 5)
"""Minimum time between domain restarts in seconds."""
-MINIMUM_RESTART_TIME = 60
+MINIMUM_RESTART_TIME = 10
RESTART_IN_PROGRESS = 'xend/restart_in_progress'
DUMPCORE_IN_PROGRESS = 'xend/dumpcore_in_progress'
++++++ xend-multi-xvdp.patch ++++++
Allow multiple bootloader loopback devices
Starting several domains concurrently can fail due to using a single
bootloader loopback device. This patch creates a list of bootloader
loopback devices so more than one instance of bootloader can be run
concurrently.
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -76,7 +76,7 @@ from xen.xend.XendPSCSI import XendPSCSI
from xen.xend.XendDSCSI import XendDSCSI, XendDSCSI_HBA
MIGRATE_TIMEOUT = 30.0
-BOOTLOADER_LOOPBACK_DEVICE = '/dev/xvdp'
+BOOTLOADER_LOOPBACK_DEVICES = ['/dev/xvd' + chr(x) for x in range(ord('z'), ord('d'), -1)]
xc = xen.lowlevel.xc.xc()
xoptions = XendOptions.instance()
@@ -3343,33 +3343,38 @@ class XendDomainInfo:
# This is a file, not a device. pygrub can cope with a
# file if it's raw, but if it's QCOW or other such formats
# used through blktap, then we need to mount it first.
-
- log.info("Mounting %s on %s." %
- (fn, BOOTLOADER_LOOPBACK_DEVICE))
-
- vbd = {
- 'mode': 'RW',
- 'device': BOOTLOADER_LOOPBACK_DEVICE,
- }
-
- from xen.xend import XendDomain
- dom0 = XendDomain.instance().privilegedDomain()
- mounted_vbd_uuid = dom0.create_vbd(vbd, disk);
- vbd_uuid = dom0.create_vbd(vbd, disk)
- dom0._waitForDeviceFrontUUID(vbd_uuid)
- fn = BOOTLOADER_LOOPBACK_DEVICE
-
+ # Try all possible loopback_devices
+ for loopback_device in BOOTLOADER_LOOPBACK_DEVICES:
+ log.info("Mounting %s on %s." % (fn, loopback_device))
+ vbd = { 'mode' : 'RW', 'device' : loopback_device, }
+ try:
+ from xen.xend import XendDomain
+ dom0 = XendDomain.instance().privilegedDomain()
+ mounted_vbd_uuid = dom0.create_vbd(vbd, disk)
+ dom0._waitForDeviceFrontUUID(mounted_vbd_uuid)
+ fn = loopback_device
+ break
+ except VmError, e:
+ if str(e).find('already connected.') != -1:
+ continue
+ elif str(e).find('isn\'t accessible') != -1:
+ dom0.destroyDevice('vbd', loopback_device, force = True, rm_cfg = True)
+ continue
+ else:
+ raise
+ else:
+ raise
try:
blcfg = bootloader(blexec, fn, self, False,
bootloader_args, kernel, ramdisk, args)
finally:
if mounted:
log.info("Unmounting %s from %s." %
- (fn, BOOTLOADER_LOOPBACK_DEVICE))
+ (fn, loopback_device))
if devtype in ['tap', 'tap2']:
- dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE, rm_cfg = True)
+ dom0.destroyDevice('tap', loopback_device, rm_cfg = True)
else:
- dom0.destroyDevice('vbd', BOOTLOADER_LOOPBACK_DEVICE, rm_cfg = True)
+ dom0.destroyDevice('vbd', loopback_device, rm_cfg = True)
if blcfg is None:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
++++++ xend-pvscsi-recognize-also-SCSI-CDROM-devices.patch ++++++
From: Olaf Hering
Date: Tue, 11 Feb 2014 15:21:01 +0100
Subject: xend/pvscsi: recognize also SCSI CDROM devices
Attaching a CDROM device with 'xm scsi-attach domU /dev/sr0 0:0:0:0'
fails because for some reason the sr driver was not handled at all in
the match list. With the change the above command succeeds and the
device is attached.
Signed-off-by: Olaf Hering
---
tools/python/xen/util/vscsi_util.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/python/xen/util/vscsi_util.py b/tools/python/xen/util/vscsi_util.py
--- a/tools/python/xen/util/vscsi_util.py
+++ b/tools/python/xen/util/vscsi_util.py
@@ -66,6 +66,9 @@ def _vscsi_get_hctl_by(phyname, scsi_devices):
if re.match('/dev/sd[a-z]+([1-9]|1[0-5])?$', phyname):
# sd driver
name = re.sub('(^/dev/)|([1-9]|1[0-5])?$', '', phyname)
+ elif re.match('/dev/sr[0-9]+$', phyname):
+ # sr driver
+ name = re.sub('^/dev/', '', phyname)
elif re.match('/dev/sg[0-9]+$', phyname):
# sg driver
name = re.sub('^/dev/', '', phyname)
++++++ xend-relocation-server.fw ++++++
## Name: Xend Relocation Server
## Description: Enables xend relocation service
TCP="8002 8003"
++++++ xend-relocation.sh ++++++
#!/bin/bash
#============================================================================
# xend-relocation
#
# Version = 1.0.3
# Date = 2007-09-14
#
# Maintainer(s) = Ron Terry - ron (at) pronetworkconsulting (dot) com
#
# The latest version can be found at:
#
# http://pronetworkconsulting.com/linux/scripts/xend-relocation.html
#
# Description:
#
# This script is used to enable or disable the VM relocation (migration)
# feature of xend. It can be used to manage the local instance of xend
# or both the local instance and instances of xend on the other machines
# to/from which VMs can be relocated.
# To manage the instances of xend on other machines this script communicates
# using ssh so it is recomended that if you use this feature you
# pre-distribute ssh keys between the servers.
#
# Depends on:
#
# Can use: /etc/sysconfig/xend
#
# Usage: xend-relocation (start|stop|status)
# or
# xend-relocation (on|off|status)
#
# Vars:
#
# XEN_CONFIG_FILE
#
# RELOCATION_NODELIST
#
# MANAGE_ALL_RELOCATION_NODES
#
# XEN_RELOCATION_PORT
#
#============================================================================
#### Read config files and set variables ##################################
# If you source the /etc/sysconfig/xend file comment out the variables
# being set in this script.
. /etc/sysconfig/xend
XEN_CONFIG_FILE="/etc/xen/xend-config.sxp"
#### Script Functions #####################################################
usage(){
echo ""
echo "Usage: xend-relocation {start|stop|status}"
echo " or"
echo " xend-relocation {on|off|status}"
echo ""
}
relocate_on() {
for NODE in $RELOCATION_NODELIST
do
case $NODE in
any)
SSHCMD=""
RELOCATION_NODELIST=""
;;
*)
if [ "$MANAGE_ALL_RELOCATION_NODES" = "true" ]
then
SSHCMD="ssh root@$NODE "
else
SSHCMD=""
fi
;;
esac
$SSHCMD sed -i "s/^#(xend-relocation-server yes)/(xend-relocation-server yes)/g" $XEN_CONFIG_FILE
$SSHCMD sed -i "s/^#(xend-relocation-server no)/(xend-relocation-server yes)/g" $XEN_CONFIG_FILE
$SSHCMD sed -i "s/^#(xend-relocation-port [^)]*)/(xend-relocation-port $XEN_RELOCATION_PORT)/g" $XEN_CONFIG_FILE
$SSHCMD sed -i "s/^(xend-relocation-hosts-allow \(.*\)/###(xend-relocation-hosts-allow \1/g" $XEN_CONFIG_FILE
$SSHCMD sed -i "s/^#(xend-relocation-hosts-allow .*/(xend-relocation-hosts-allow \'$RELOCATION_NODELIST')/g" $XEN_CONFIG_FILE
$SSHCMD rcxend restart
if [ "$NODE" = "any" ] || [ "$MANAGE_ALL_RELOCATION_NODES" = "false" ]
then
exit 0
fi
done
}
relocate_off() {
for NODE in $RELOCATION_NODELIST
do
case $NODE in
any)
SSHCMD=""
RELOCATION_NODELIST=""
;;
*)
SSHCMD="ssh root@$NODE "
;;
esac
$SSHCMD sed -i "s/^(xend-relocation-server yes)/#(xend-relocation-server yes)/g" $XEN_CONFIG_FILE
$SSHCMD sed -i "s/^(xend-relocation-port [^)]*)/#(xend-relocation-port $XEN_RELOCATION_PORT)/g" $XEN_CONFIG_FILE
$SSHCMD sed -i "s/^(xend-relocation-hosts-allow .*/#(xend-relocation-hosts-allow \'$RELOCATION_NODELIST')/g" $XEN_CONFIG_FILE
$SSHCMD rcxend restart
if [ "$NODE" = "any" ] || [ "$MANAGE_ALL_RELOCATION_NODES" = "false" ]
then
exit 0
fi
done
}
relocate_status() {
if grep -q "^(xend-relocation-server .*yes)" $XEN_CONFIG_FILE
then
ENABLED="yes"
elif egrep -q "(^\(xend-relocation-server .*no\)|^#\(xend-relocation-server .*no\)|^#\(xend-relocation-server .*yes\))" $XEN_CONFIG_FILE
then
ENABLED="no"
fi
echo ""
echo "Xend Relocation Server Enabled: $ENABLED"
echo ""
}
#### Script Body ##########################################################
case $1 in
on|ON|On|start)
case $ENABLE_RELOCATION in
true)
relocate_on
;;
false)
;;
esac
exit 0
;;
off|OFF|Off|stop)
relocate_off
exit 0
;;
status|STATUS|Status)
relocate_status
exit 0
;;
*)
usage
exit 1
;;
esac
++++++ xend-remove-xm-deprecation-warning.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xm/xm
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/xm
+++ xen-4.4.0-testing/tools/python/xen/xm/xm
@@ -4,17 +4,17 @@ import sys, os.path
from xen.xm import main
-print >>sys.stderr, ("WARNING: xend/xm is deprecated.")
-
-if not os.path.exists("/var/run/xm-deprecation-long-warning"):
- print >>sys.stderr, ("""
-xend is deprecated and scheduled for removal. Please migrate to another
-toolstack ASAP.
-
-See http://wiki.xen.org/wiki/Choice_of_Toolstacks for information on
-other alternatives, including xl which is designed to be a drop in
-replacement for xm (http://wiki.xen.org/wiki/XL).
-""")
- open("/var/run/xm-deprecation-long-warning", "w").close()
+#print >>sys.stderr, ("WARNING: xend/xm is deprecated.")
+#
+#if not os.path.exists("/var/run/xm-deprecation-long-warning"):
+# print >>sys.stderr, ("""
+#xend is deprecated and scheduled for removal. Please migrate to another
+#toolstack ASAP.
+#
+#See http://wiki.xen.org/wiki/Choice_of_Toolstacks for information on
+#other alternatives, including xl which is designed to be a drop in
+#replacement for xm (http://wiki.xen.org/wiki/XL).
+#""")
+# open("/var/run/xm-deprecation-long-warning", "w").close()
main.main(sys.argv)
++++++ xend-set-migration-constraints-from-cmdline.patch ++++++
From aa0cecb067ca6077c67cfc13f0ce31af7a3b72bb Mon Sep 17 00:00:00 2001
From: Olaf Hering
Date: Mon, 10 Feb 2014 09:43:40 +0100
Subject: xend: set migration constraints from cmdline
xend part of required libxl change to tweak parameters of xc_domain_save
Add xm migrate --log_progress option. xc_domain_save does print progress
messages. These verbose messages are disabled per default to avoid flood
in xend.log. Sometimes it is helpful to see progress when migrating
large and busy guests. So add a new option to xm migrate to actually
enable the printing of progress messsages.
Print messages from xc_save with xc_report. Make use of xc_report in
xc_save to log also pid if some error occoured.
Signed-off-by: Olaf Hering
---
tools/libxc/xc_private.h | 1 +
tools/libxc/xenguest.h | 1 +
tools/python/xen/xend/XendCheckpoint.py | 22 +++++++++-
tools/python/xen/xend/XendDomain.py | 14 ++++++
tools/python/xen/xend/XendDomainInfo.py | 16 +++++++
tools/python/xen/xm/migrate.py | 26 +++++++++++
tools/xcutils/xc_save.c | 76 +++++++++++++++++++++------------
7 files changed, 127 insertions(+), 29 deletions(-)
Index: xen-4.4.1-testing/tools/libxc/xc_private.h
===================================================================
--- xen-4.4.1-testing.orig/tools/libxc/xc_private.h
+++ xen-4.4.1-testing/tools/libxc/xc_private.h
@@ -119,6 +119,7 @@ void xc_report_progress_step(xc_interfac
/* anamorphic macros: struct xc_interface *xch must be in scope */
+#define WPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_WARN,0, _f , ## _a)
#define IPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_INFO,0, _f , ## _a)
#define DPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DETAIL,0, _f , ## _a)
#define DBGPRINTF(_f, _a...) xc_report(xch, xch->error_handler, XTL_DEBUG,0, _f , ## _a)
Index: xen-4.4.1-testing/tools/libxc/xenguest.h
===================================================================
--- xen-4.4.1-testing.orig/tools/libxc/xenguest.h
+++ xen-4.4.1-testing/tools/libxc/xenguest.h
@@ -29,6 +29,7 @@
#define XCFLAGS_STDVGA (1 << 3)
#define XCFLAGS_CHECKPOINT_COMPRESS (1 << 4)
#define XCFLAGS_DOMSAVE_ABORT_IF_BUSY (1 << 5)
+#define XCFLAGS_PROGRESS (1 << 6)
#define X86_64_B_SIZE 64
#define X86_32_B_SIZE 32
Index: xen-4.4.1-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.4.1-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -118,9 +118,27 @@ def save(fd, dominfo, network, live, dst
# enabled. Passing "0" simply uses the defaults compiled into
# libxenguest; see the comments and/or code in xc_linux_save() for
# more information.
+ max_iters = dominfo.info.get('max_iters', "0")
+ max_factor = dominfo.info.get('max_factor', "0")
+ min_remaining = dominfo.info.get('min_remaining', "0")
+ abort_if_busy = dominfo.info.get('abort_if_busy', "0")
+ log_save_progress = dominfo.info.get('log_save_progress', "0")
+ if max_iters == "None":
+ max_iters = "0"
+ if max_factor == "None":
+ max_factor = "0"
+ if min_remaining == "None":
+ min_remaining = "0"
+ if abort_if_busy == "None":
+ abort_if_busy = "0"
+ if log_save_progress == "None":
+ log_save_progress = "0"
cmd = [xen.util.auxbin.pathTo(XC_SAVE), str(fd),
- str(dominfo.getDomid()), "0", "0",
- str(int(live) | (int(hvm) << 2)) ]
+ str(dominfo.getDomid()),
+ max_iters, max_factor,
+ str( int(live) | (int(hvm) << 2) | (int(abort_if_busy) << 5) | (int(log_save_progress) << 6) ),
+ min_remaining
+ ]
log.debug("[xc_save]: %s", string.join(cmd))
def saveInputHandler(line, tochild):
Index: xen-4.4.1-testing/tools/python/xen/xend/XendDomain.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/XendDomain.py
+++ xen-4.4.1-testing/tools/python/xen/xend/XendDomain.py
@@ -1832,6 +1832,20 @@ class XendDomain:
log.exception(ex)
raise XendError(str(ex))
+ def domain_migrate_constraints_set(self, domid, max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress):
+ """Set the Migrate Constraints of this domain.
+ @param domid: Domain ID or Name
+ @param max_iters: Number of iterations before final suspend
+ @param max_factor: Max amount of memory to transfer before final suspend
+ @param min_remaining: Number of dirty pages before final suspend
+ @param abort_if_busy: Abort migration instead of doing final suspend
+ @param log_save_progress: Log progress of migrate to xend.log
+ """
+ dominfo = self.domain_lookup_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+ dominfo.setMigrateConstraints(max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress)
+
def domain_maxmem_set(self, domid, mem):
"""Set the memory limit for a domain.
Index: xen-4.4.1-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1461,6 +1461,22 @@ class XendDomainInfo:
pci_conf = self.info['devices'][dev_uuid][1]
return map(pci_dict_to_bdf_str, pci_conf['devs'])
+ def setMigrateConstraints(self, max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress):
+ """Set the Migrate Constraints of this domain.
+ @param max_iters: Number of iterations before final suspend
+ @param max_factor: Max amount of memory to transfer before final suspend
+ @param min_remaining: Number of dirty pages before final suspend
+ @param abort_if_busy: Abort migration instead of doing final suspend
+ @param log_save_progress: Log progress of migrate to xend.log
+ """
+ log.debug("Setting migration constraints of domain %s (%s) to '%s' '%s' '%s' '%s'.",
+ self.info['name_label'], str(self.domid), max_iters, max_factor, min_remaining, abort_if_busy)
+ self.info['max_iters'] = str(max_iters)
+ self.info['max_factor'] = str(max_factor)
+ self.info['min_remaining'] = str(min_remaining)
+ self.info['abort_if_busy'] = str(abort_if_busy)
+ self.info['log_save_progress'] = str(log_save_progress)
+
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
Index: xen-4.4.1-testing/tools/python/xen/xm/migrate.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xm/migrate.py
+++ xen-4.4.1-testing/tools/python/xen/xm/migrate.py
@@ -55,6 +55,26 @@ gopts.opt('change_home_server', short='c
fn=set_true, default=0,
use="Change home server for managed domains.")
+gopts.opt('max_iters', val='max_iters',
+ fn=set_int, default=0,
+ use="Number of iterations before final suspend (default: 30).")
+
+gopts.opt('max_factor', val='max_factor',
+ fn=set_int, default=0,
+ use="Max amount of memory to transfer before final suspend (default: 3*RAM).")
+
+gopts.opt('min_remaining', val='min_remaining',
+ fn=set_int, default=0,
+ use="Number of dirty pages before final suspend (default: 50).")
+
+gopts.opt('abort_if_busy',
+ fn=set_true, default=0,
+ use="Abort migration instead of doing final suspend.")
+
+gopts.opt('log_progress',
+ fn=set_true, default=0,
+ use="Log progress of migration to xend.log")
+
def help():
return str(gopts)
@@ -80,6 +100,12 @@ def main(argv):
server.xenapi.VM.migrate(vm_ref, dst, bool(opts.vals.live),
other_config)
else:
+ server.xend.domain.migrate_constraints_set(dom,
+ opts.vals.max_iters,
+ opts.vals.max_factor,
+ opts.vals.min_remaining,
+ opts.vals.abort_if_busy,
+ opts.vals.log_progress)
server.xend.domain.migrate(dom, dst, opts.vals.live,
opts.vals.port,
opts.vals.node,
Index: xen-4.4.1-testing/tools/xcutils/xc_save.c
===================================================================
--- xen-4.4.1-testing.orig/tools/xcutils/xc_save.c
+++ xen-4.4.1-testing/tools/xcutils/xc_save.c
@@ -7,6 +7,7 @@
*
*/
+#include
#include
#include
#include
@@ -19,6 +20,7 @@
#include
#include
+#include
#include
#include
#include
@@ -51,16 +53,17 @@ static int compat_suspend(void)
* receive the acknowledgement from the subscribe event channel. */
static int evtchn_suspend(void)
{
+ xc_interface *xch = si.xch;
int rc;
rc = xc_evtchn_notify(si.xce, si.suspend_evtchn);
if (rc < 0) {
- warnx("failed to notify suspend request channel: %d", rc);
+ WPRINTF("failed to notify suspend request channel: %d", rc);
return 0;
}
- if (xc_await_suspend(si.xch, si.xce, si.suspend_evtchn) < 0) {
- warnx("suspend failed");
+ if (xc_await_suspend(xch, si.xce, si.suspend_evtchn) < 0) {
+ WPRINTF("suspend failed");
return 0;
}
@@ -104,20 +107,27 @@ static int suspend(void* data)
static int switch_qemu_logdirty(int domid, unsigned int enable, void *data)
{
+ xc_interface *xch = si.xch;
struct xs_handle *xs;
char *path, *p, *ret_str, *cmd_str, **watch;
unsigned int len;
struct timeval tv;
fd_set fdset;
- if ((xs = xs_daemon_open()) == NULL)
- errx(1, "Couldn't contact xenstore");
- if (!(path = strdup("/local/domain/0/device-model/")))
- errx(1, "can't get domain path in store");
+ if ((xs = xs_daemon_open()) == NULL) {
+ PERROR("Couldn't contact xenstore");
+ exit(1);
+ }
+ if (!(path = strdup("/local/domain/0/device-model/"))) {
+ PERROR("can't get domain path in store");
+ exit(1);
+ }
if (!(path = realloc(path, strlen(path)
+ 10
- + strlen("/logdirty/cmd") + 1)))
- errx(1, "no memory for constructing xenstore path");
+ + strlen("/logdirty/cmd") + 1))) {
+ PERROR("no memory for constructing xenstore path");
+ exit(1);
+ }
snprintf(path + strlen(path), 11, "%i", domid);
strcat(path, "/logdirty/");
p = path + strlen(path);
@@ -126,16 +136,22 @@ static int switch_qemu_logdirty(int domi
/* Watch for qemu's return value */
strcpy(p, "ret");
if (!xs_watch(xs, path, "qemu-logdirty-ret"))
- errx(1, "can't set watch in store (%s)\n", path);
+ {
+ ERROR("can't set watch in store (%s)\n", path);
+ exit(1);
+ }
- if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable")))
- errx(1, "can't get logdirty cmd path in store");
+ if (!(cmd_str = strdup( enable == 0 ? "disable" : "enable"))) {
+ PERROR("can't get logdirty cmd path in store");
+ exit(1);
+ }
/* Tell qemu that we want it to start logging dirty page to Xen */
strcpy(p, "cmd");
- if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str)))
- errx(1, "can't write to store path (%s)\n",
- path);
+ if (!xs_write(xs, XBT_NULL, path, cmd_str, strlen(cmd_str))) {
+ PERROR("can't write to store path (%s)\n", path);
+ exit(1);
+ }
/* Wait a while for qemu to signal that it has service logdirty command */
read_again:
@@ -144,8 +160,10 @@ static int switch_qemu_logdirty(int domi
FD_ZERO(&fdset);
FD_SET(xs_fileno(xs), &fdset);
- if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1)
- errx(1, "timed out waiting for qemu logdirty response.\n");
+ if ((select(xs_fileno(xs) + 1, &fdset, NULL, NULL, &tv)) != 1) {
+ PERROR("timed out waiting for qemu logdirty response.\n");
+ exit(1);
+ }
watch = xs_read_watch(xs, &len);
free(watch);
@@ -166,53 +184,57 @@ static int switch_qemu_logdirty(int domi
int
main(int argc, char **argv)
{
- unsigned int maxit, max_f, lflags;
+ xc_interface *xch;
+ unsigned int maxit, max_f, lflags, min_r;
int io_fd, ret, port;
struct save_callbacks callbacks;
xentoollog_level lvl;
xentoollog_logger *l;
- if (argc != 6)
- errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]);
+ if (argc != 7)
+ errx(1, "usage: %s iofd domid maxit maxf flags minr", argv[0]);
io_fd = atoi(argv[1]);
si.domid = atoi(argv[2]);
maxit = atoi(argv[3]);
max_f = atoi(argv[4]);
si.flags = atoi(argv[5]);
+ min_r = atoi(argv[6]);
si.suspend_evtchn = -1;
lvl = si.flags & XCFLAGS_DEBUG ? XTL_DEBUG: XTL_DETAIL;
- lflags = XTL_STDIOSTREAM_SHOW_PID | XTL_STDIOSTREAM_HIDE_PROGRESS;
+ lflags = XTL_STDIOSTREAM_SHOW_PID;
+ if (si.flags & XCFLAGS_PROGRESS)
+ lflags |= XTL_STDIOSTREAM_HIDE_PROGRESS;
l = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, lvl, lflags);
- si.xch = xc_interface_open(l, 0, 0);
+ xch = si.xch = xc_interface_open(l, 0, 0);
if (!si.xch)
- errx(1, "failed to open control interface");
+ errx(1, "[%lu] failed to open control interface", (unsigned long)getpid());
si.xce = xc_evtchn_open(NULL, 0);
if (si.xce == NULL)
- warnx("failed to open event channel handle");
+ WPRINTF("failed to open event channel handle");
else
{
port = xs_suspend_evtchn_port(si.domid);
if (port < 0)
- warnx("failed to get the suspend evtchn port\n");
+ WPRINTF("failed to get the suspend evtchn port\n");
else
{
si.suspend_evtchn =
xc_suspend_evtchn_init(si.xch, si.xce, si.domid, port);
if (si.suspend_evtchn < 0)
- warnx("suspend event channel initialization failed, "
+ WPRINTF("suspend event channel initialization failed, "
"using slow path");
}
}
memset(&callbacks, 0, sizeof(callbacks));
callbacks.suspend = suspend;
callbacks.switch_qemu_logdirty = switch_qemu_logdirty;
- ret = xc_domain_save(si.xch, io_fd, si.domid, maxit, max_f, si.flags,
+ ret = xc_domain_save_suse(si.xch, io_fd, si.domid, maxit, max_f, min_r, si.flags,
&callbacks, !!(si.flags & XCFLAGS_HVM), 0);
if (si.suspend_evtchn > 0)
Index: xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py
===================================================================
--- xen-4.4.1-testing.orig/tools/python/xen/xend/server/SrvDomain.py
+++ xen-4.4.1-testing/tools/python/xen/xend/server/SrvDomain.py
@@ -108,6 +108,17 @@ class SrvDomain(SrvDir):
['reset', 'int']])
return fn(req.args, {'dom': self.dom.domid})
+ def op_migrate_constraints_set(self, _, req):
+ self.acceptCommand(req)
+ fn = FormFn(self.xd.domain_migrate_constraints_set,
+ [['dom', 'int'],
+ ['max_iters', 'int'],
+ ['max_factor', 'int'],
+ ['min_remaining', 'int'],
+ ['abort_if_busy', 'int'],
+ ['log_progress', 'int']])
+ return fn(req.args, {'dom': self.dom.domid})
+
def op_migrate(self, op, req):
return req.threadRequest(self.do_migrate, op, req)
++++++ xend-tools-watchdog-support.patch ++++++
Index: xen-4.4.3-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.4.3-testing/tools/python/xen/xm/create.py
@@ -517,6 +517,21 @@ gopts.var('usbdevice', val='NAME',
fn=set_value, default='',
use="Name of USB device to add?")
+gopts.var('watchdog', val='NAME',
+ fn=set_value, default='',
+ use="Watchdog device to use. May be ib700 or i6300esb")
+
+gopts.var('watchdog_action', val='reset|shutdown|poweroff|pause|none|dump',
+ fn=set_value, default="reset",
+ use="""Action when watchdog timer expires:
+ - reset: Default, forcefully reset the guest;
+ - shutdown: Gracefully shutdown the guest (not recommended);
+ - poweroff: Forcefully power off the guest;
+ - pause: Pause the guest;
+ - none: Do nothing;
+ - dump: Automatically dump the guest;
+ """)
+
gopts.var('description', val='NAME',
fn=set_value, default='',
use="Description of a domain")
@@ -1048,6 +1063,7 @@ def configure_hvm(config_image, vals):
'usb', 'usbdevice',
'vcpus', 'vnc', 'vncconsole', 'vncdisplay', 'vnclisten',
'vncunused', 'viridian', 'vpt_align',
+ 'watchdog', 'watchdog_action',
'xauthority', 'xen_extended_power_mgmt', 'xen_platform_pci',
'memory_sharing' ]
Index: xen-4.4.3-testing/tools/python/xen/xm/xenapi_create.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xm/xenapi_create.py
+++ xen-4.4.3-testing/tools/python/xen/xm/xenapi_create.py
@@ -1074,7 +1074,9 @@ class sxp2xml:
'xen_platform_pci',
'tsc_mode'
'description',
- 'nomigrate'
+ 'nomigrate',
+ 'watchdog',
+ 'watchdog_action'
]
platform_configs = []
Index: xen-4.4.3-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.4.3-testing/tools/python/xen/xend/image.py
@@ -855,7 +855,8 @@ class HVMImageHandler(ImageHandler):
dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
'localtime', 'serial', 'stdvga', 'isa',
- 'acpi', 'usb', 'usbdevice', 'gfx_passthru' ]
+ 'acpi', 'usb', 'usbdevice', 'gfx_passthru',
+ 'watchdog', 'watchdog_action' ]
for a in dmargs:
v = vmConfig['platform'].get(a)
@@ -863,6 +864,7 @@ class HVMImageHandler(ImageHandler):
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
if a == 'keymap': a = 'k'
+ if a == 'watchdog_action': a = 'watchdog-action'
# Handle booleans gracefully
if a in ['localtime', 'std-vga', 'isa', 'usb', 'acpi']:
Index: xen-4.4.3-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.4.3-testing/tools/python/xen/xend/XendConfig.py
@@ -192,6 +192,8 @@ XENAPI_PLATFORM_CFG_TYPES = {
'xen_platform_pci': int,
"gfx_passthru": int,
'oos' : int,
+ 'watchdog': str,
+ 'watchdog_action': str,
}
# Xen API console 'other_config' keys.
Index: xen-4.4.3-testing/tools/libxl/libxl_dm.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_dm.c
+++ xen-4.4.3-testing/tools/libxl/libxl_dm.c
@@ -266,6 +266,12 @@ static char ** libxl__build_device_model
}
}
}
+ if (b_info->u.hvm.watchdog || b_info->u.hvm.watchdog_action) {
+ flexarray_append(dm_args, "-watchdog");
+ if (b_info->u.hvm.watchdog_action) {
+ flexarray_vappend(dm_args, "-watchdog-action", b_info->u.hvm.watchdog_action, NULL);
+ }
+ }
if (b_info->u.hvm.soundhw) {
flexarray_vappend(dm_args, "-soundhw", b_info->u.hvm.soundhw, NULL);
}
@@ -637,6 +643,12 @@ static char ** libxl__build_device_model
return NULL;
}
}
+ if (b_info->u.hvm.watchdog || b_info->u.hvm.watchdog_action) {
+ flexarray_append(dm_args, "-watchdog");
+ if (b_info->u.hvm.watchdog_action) {
+ flexarray_vappend(dm_args, "-watchdog-action", b_info->u.hvm.watchdog_action, NULL);
+ }
+ }
if (b_info->u.hvm.soundhw) {
flexarray_vappend(dm_args, "-soundhw", b_info->u.hvm.soundhw, NULL);
}
Index: xen-4.4.3-testing/tools/libxl/libxl_types.idl
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_types.idl
+++ xen-4.4.3-testing/tools/libxl/libxl_types.idl
@@ -377,6 +377,8 @@ libxl_domain_build_info = Struct("domain
("xen_platform_pci", libxl_defbool),
("usbdevice_list", libxl_string_list),
("vendor_device", libxl_vendor_device),
+ ("watchdog", string),
+ ("watchdog_action", string),
])),
("pv", Struct(None, [("kernel", string),
("slack_memkb", MemKB),
Index: xen-4.4.3-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.4.3-testing/tools/libxl/xl_cmdimpl.c
@@ -1928,6 +1928,8 @@ skip_vfb:
xlu_cfg_replace_string (config, "soundhw", &b_info->u.hvm.soundhw, 0);
xlu_cfg_get_defbool(config, "xen_platform_pci",
&b_info->u.hvm.xen_platform_pci, 0);
+ xlu_cfg_replace_string (config, "watchdog", &b_info->u.hvm.watchdog, 0);
+ xlu_cfg_replace_string (config, "watchdog_action", &b_info->u.hvm.watchdog_action, 0);
if(b_info->u.hvm.vnc.listen
&& b_info->u.hvm.vnc.display
++++++ xend-vcpu-affinity-fix.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -2806,7 +2806,10 @@ class XendDomainInfo:
from xen.xend import XendDomain
doms = XendDomain.instance().list('all')
for dom in filter (lambda d: d.domid != self.domid, doms):
- cpuinfo = dom.getVCPUInfo()
+ try:
+ cpuinfo = dom.getVCPUInfo()
+ except:
+ continue
for vcpu in sxp.children(cpuinfo, 'vcpu'):
if sxp.child_value(vcpu, 'online') == 0: continue
cpumap = list(sxp.child_value(vcpu,'cpumap'))
++++++ xend-vif-route-ifup.patch ++++++
---
tools/examples/xend-config.sxp | 20 ++++++++++++++++++++
tools/hotplug/Linux/Makefile | 2 +-
tools/hotplug/Linux/vif-route-ifup | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 1 deletion(-)
Index: xen-4.4.0-testing/tools/examples/xend-config.sxp
===================================================================
--- xen-4.4.0-testing.orig/tools/examples/xend-config.sxp
+++ xen-4.4.0-testing/tools/examples/xend-config.sxp
@@ -200,6 +200,26 @@
#(network-script network-route)
#(vif-script vif-route)
+# SUSE users note:
+# If using a routed network configuration it is advised to NOT use
+# network-route and vif-route scripts but instead use sysconfig scripts
+# in dom0 and vif-route-ifup script to "connect" the domU vif to dom0.
+# Since this configuration requires a vif sysconfig script in dom0, a static
+# vif name must be used. E.g. in dom0 the vif sysconfig script
+# (/etc/sysconfig/network/ifcfg-xen1.0) may contain
+#
+# NAME='XEN vm 1 virtual interface 0'
+# BOOTPROTO='static'
+# STARTMODE='hotplug'
+# ...
+#
+# The corresponding domain vif configuration would contain e.g.
+# vif=[ 'mac=00:16:3e:aa:bb:cc,script=vif-route-ifup,vifname=xen1.0', ]
+#
+# If the vif-route-ifup script will be used for all domains, it can be
+# set here as the default vif script, alleviating the need for
+# 'script=' in domain vif configuration.
+#(vif-script vif-route-ifup)
## Use the following if network traffic is routed with NAT, as an alternative
# to the settings for bridged networking given above.
Index: xen-4.4.0-testing/tools/hotplug/Linux/Makefile
===================================================================
--- xen-4.4.0-testing.orig/tools/hotplug/Linux/Makefile
+++ xen-4.4.0-testing/tools/hotplug/Linux/Makefile
@@ -11,7 +11,7 @@ XENCOMMONS_SYSCONFIG = init.d/sysconfig.
# Xen script dir and scripts to go there.
XEN_SCRIPTS = network-bridge vif-bridge
-XEN_SCRIPTS += network-route vif-route
+XEN_SCRIPTS += network-route vif-route vif-route-ifup
XEN_SCRIPTS += network-nat vif-nat
XEN_SCRIPTS += vif-openvswitch
XEN_SCRIPTS += vif2
Index: xen-4.4.0-testing/tools/hotplug/Linux/vif-route-ifup
===================================================================
--- /dev/null
+++ xen-4.4.0-testing/tools/hotplug/Linux/vif-route-ifup
@@ -0,0 +1,34 @@
+#!/bin/bash
+#============================================================================
+# /etc/xen/vif-route-ifup
+#
+# Script for configuring a vif in routed mode.
+# The hotplugging system will call this script if it is specified either in
+# the device configuration given to Xend, or the default Xend configuration
+# in /etc/xen/xend-config.sxp. If the script is specified in neither of those
+# places, then vif-bridge is the default.
+#
+# Usage:
+# vif-route-ifup (add|remove|online|offline)
+#
+# Environment vars:
+# dev vif interface name (required).
+#============================================================================
+
+dir=$(dirname "$0")
+. "$dir/vif-common.sh"
+
+case "$command" in
+ online)
+ ifup ${dev}
+ ;;
+ offline)
+ do_without_error ifdown ${dev}
+ ;;
+esac
+
+log debug "Successful vif-route-ifup $command for ${dev}."
+if [ "$command" = "online" ]
+then
+ success
+fi
++++++ xend-xen-api-auth.patch ++++++
Index: xen-4.2.0-testing/tools/python/xen/xend/XendAuthSessions.py
===================================================================
--- xen-4.2.0-testing.orig/tools/python/xen/xend/XendAuthSessions.py
+++ xen-4.2.0-testing/tools/python/xen/xend/XendAuthSessions.py
@@ -84,7 +84,7 @@ class XendAuthSessions:
# if PAM doesn't exist, let's ignore it
return False
- pam_auth.start("login")
+ pam_auth.start("xen-api")
pam_auth.set_item(PAM.PAM_USER, username)
def _pam_conv(auth, query_list, user_data = None):
++++++ xend-xen-domUloader.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/server/DevController.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/server/DevController.py
+++ xen-4.4.0-testing/tools/python/xen/xend/server/DevController.py
@@ -592,6 +592,31 @@ class DevController:
return (Missing, None)
+ def waitForFrontend(self, devid):
+ def frontendStatusCallback(statusPath, ev, result):
+ status = xstransact.Read(statusPath)
+ log.debug("frontendStatusCallback %s = %s" % (statusPath, status))
+ try:
+ status = int(status)
+ if status == xenbusState['Connected']:
+ result['status'] = Connected
+ elif status == xenbusState['Closed']:
+ result['status'] = Error
+ else:
+ raise
+ except:
+ return 1
+ ev.set()
+ return 0
+ frontpath = self.frontendPath(devid)
+ statusPath = frontpath + '/state'
+ ev = Event()
+ result = { 'status': Timeout }
+ xswatch(statusPath, frontendStatusCallback, ev, result)
+ ev.wait(5)
+ return result['status']
+
+
def backendPath(self, backdom, devid):
"""Construct backend path given the backend domain and device id.
Index: xen-4.4.0-testing/tools/python/xen/xend/XendBootloader.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendBootloader.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendBootloader.py
@@ -12,7 +12,7 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-import os, select, errno, stat, signal, tty
+import os, select, errno, stat, signal, tty, time
import random
import shlex
from xen.xend import sxp
@@ -38,8 +38,25 @@ def bootloader(blexec, disk, dom, quiet
msg = "Bootloader isn't executable"
log.error(msg)
raise VmError(msg)
- if not os.access(disk, os.R_OK):
- msg = "Disk isn't accessible"
+
+ # domUloader requires '--entry=foo' in blargs, which is derived from
+ # 'bootargs' entry in domain configuration file. Ensure it exists
+ # here so a reasonable error message can be returned.
+ if blexec.find('domUloader.py') != -1:
+ if blargs.find('entry') == -1:
+ msg = "domUloader requires specification of bootargs"
+ log.error(msg)
+ raise VmError(msg)
+
+ avail = False
+ for i in xrange(1, 500):
+ avail = os.access(disk, os.R_OK)
+ if avail:
+ break
+ time.sleep(.1)
+
+ if not avail:
+ msg = "Disk '%s' isn't accessible" % disk
log.error(msg)
raise VmError(msg)
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -2401,6 +2401,10 @@ class XendDomainInfo:
deviceClass, config = self.info['devices'].get(dev_uuid)
self._waitForDevice(deviceClass, config['devid'])
+ def _waitForDeviceFrontUUID(self, dev_uuid):
+ deviceClass, config = self.info['devices'].get(dev_uuid)
+ self.getDeviceController(deviceClass).waitForFrontend(config['devid'])
+
def _waitForDevice_destroy(self, deviceClass, devid, backpath):
return self.getDeviceController(deviceClass).waitForDevice_destroy(
devid, backpath)
@@ -3351,7 +3355,8 @@ class XendDomainInfo:
from xen.xend import XendDomain
dom0 = XendDomain.instance().privilegedDomain()
mounted_vbd_uuid = dom0.create_vbd(vbd, disk);
- dom0._waitForDeviceUUID(mounted_vbd_uuid)
+ vbd_uuid = dom0.create_vbd(vbd, disk)
+ dom0._waitForDeviceFrontUUID(vbd_uuid)
fn = BOOTLOADER_LOOPBACK_DEVICE
try:
@@ -3361,10 +3366,10 @@ class XendDomainInfo:
if mounted:
log.info("Unmounting %s from %s." %
(fn, BOOTLOADER_LOOPBACK_DEVICE))
- _, vbd_info = dom0.info['devices'][mounted_vbd_uuid]
- dom0.destroyDevice(dom0.getBlockDeviceClass(vbd_info['devid']),
- BOOTLOADER_LOOPBACK_DEVICE, force = True)
-
+ if devtype in ['tap', 'tap2']:
+ dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE, rm_cfg = True)
+ else:
+ dom0.destroyDevice('vbd', BOOTLOADER_LOOPBACK_DEVICE, rm_cfg = True)
if blcfg is None:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
++++++ xend-xenapi-console-protocol.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -3964,6 +3964,14 @@ class XendDomainInfo:
else:
config['mode'] = 'RW'
+ if dev_class == 'console':
+ if not config.has_key('protocol'):
+ con_type = config.get('type', '')
+ if con_type == 'vnc':
+ config['protocol'] = 'rfb'
+ elif con_type == 'sdl':
+ config['protocol'] = 'rdp'
+
return config
def get_dev_property(self, dev_class, dev_uuid, field):
++++++ xend-xenpaging.autostart.patch ++++++
# HG changeset patch
# Parent 659ee31faec91ac543578db7c9b2849fb7367419
xenpaging: xend: start xenpaging via config option
Start xenpaging via config option.
TODO: add libxl support
TODO: parse config values like 42K, 42M, 42G, 42%
Signed-off-by: Olaf Hering
---
v5:
use actmem=, xenpaging_file=, xenpaging_extra=
add xm mem-swap-target
v4:
add config option for pagefile directory
add config option to enable debug
add config option to set policy mru_size
fail if chdir fails
force self.xenpaging* variables to be strings because a xm new may turn some
of them into type int and later os.execve fails with a TypeError
v3:
decouple create/destroycreateXenPaging from _create/_removeDevices
init xenpaging variable to 0 if xenpaging is not in config file to
avoid string None coming from sxp file
v2:
unlink logfile instead of truncating it.
allows hardlinking for further inspection
---
tools/examples/xmexample.hvm | 9 +++
tools/python/README.XendConfig | 3 +
tools/python/README.sxpcfg | 3 +
tools/python/xen/xend/XendConfig.py | 9 +++
tools/python/xen/xend/XendDomain.py | 15 +++++
tools/python/xen/xend/XendDomainInfo.py | 23 ++++++++
tools/python/xen/xend/image.py | 85 ++++++++++++++++++++++++++++++++
tools/python/xen/xm/create.py | 15 +++++
tools/python/xen/xm/main.py | 14 +++++
tools/python/xen/xm/xenapi_create.py | 3 +
10 files changed, 179 insertions(+)
Index: xen-4.4.0-testing/tools/examples/xmexample.hvm
===================================================================
--- xen-4.4.0-testing.orig/tools/examples/xmexample.hvm
+++ xen-4.4.0-testing/tools/examples/xmexample.hvm
@@ -142,6 +142,15 @@ disk = [ 'file:/var/lib/xen/images/disk.
# Device Model to be used
device_model = 'qemu-dm'
+# the amount of memory in MiB for the guest
+#actmem=42
+
+# Optional: guest page file
+#xenpaging_file="/var/lib/xen/xenpaging/..paging"
+
+# Optional: extra cmdline options for xenpaging
+#xenpaging_extra=[ 'string', 'string' ]
+
#-----------------------------------------------------------------------------
# boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d)
# default: hard disk, cd-rom, floppy
Index: xen-4.4.0-testing/tools/python/README.XendConfig
===================================================================
--- xen-4.4.0-testing.orig/tools/python/README.XendConfig
+++ xen-4.4.0-testing/tools/python/README.XendConfig
@@ -118,6 +118,9 @@ otherConfig
image.vncdisplay
image.vncunused
image.hvm.device_model
+ image.hvm.actmem
+ image.hvm.xenpaging_file
+ image.hvm.xenpaging_extra
image.hvm.smbios_firmware
image.hvm.apci_firmware
image.hvm.display
Index: xen-4.4.0-testing/tools/python/README.sxpcfg
===================================================================
--- xen-4.4.0-testing.orig/tools/python/README.sxpcfg
+++ xen-4.4.0-testing/tools/python/README.sxpcfg
@@ -51,6 +51,9 @@ image
- vncunused
(HVM)
- device_model
+ - actmem
+ - xenpaging_file
+ - xenpaging_extra
- smbios_firmware
- acpi_firmware
- display
Index: xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendConfig.py
@@ -147,6 +147,9 @@ XENAPI_PLATFORM_CFG_TYPES = {
'apic': int,
'boot': str,
'device_model': str,
+ 'actmem': str,
+ 'xenpaging_file': str,
+ 'xenpaging_extra': str,
'smbios_firmware': str,
'acpi_firmware': str,
'loader': str,
@@ -517,6 +520,12 @@ class XendConfig(dict):
self['platform']['nomigrate'] = 0
if self.is_hvm():
+ if 'actmem' not in self['platform']:
+ self['platform']['actmem'] = "0"
+ if 'xenpaging_file' not in self['platform']:
+ self['platform']['xenpaging_file'] = ""
+ if 'xenpaging_extra' not in self['platform']:
+ self['platform']['xenpaging_extra'] = []
if 'smbios_firmware' not in self['platform']:
self['platform']['smbios_firmware'] = ""
if 'acpi_firmware' not in self['platform']:
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomain.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
@@ -1849,6 +1849,21 @@ class XendDomain:
raise XendInvalidDomain(str(domid))
dominfo.setMigrateConstraints(max_iters, max_factor, min_remaining, abort_if_busy, log_save_progress)
+ def domain_swaptarget_set(self, domid, mem):
+ """Set the memory limit for a domain.
+
+ @param domid: Domain ID or Name
+ @type domid: int or string.
+ @param mem: memory limit (in MiB)
+ @type mem: int
+ @raise XendError: fail to set memory
+ @rtype: 0
+ """
+ dominfo = self.domain_lookup_nr(domid)
+ if not dominfo:
+ raise XendInvalidDomain(str(domid))
+ dominfo.setSwapTarget(mem)
+
def domain_maxmem_set(self, domid, mem):
"""Set the memory limit for a domain.
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -1549,6 +1549,17 @@ class XendDomainInfo:
target = max_target
self.setMemoryTarget(target)
+ def setSwapTarget(self, target):
+ """Set the swap target of this domain.
+ @param target: In MiB.
+ """
+ log.debug("Setting swap target of domain %s (%s) to %d MiB.",
+ self.info['name_label'], str(self.domid), target)
+
+ if self.domid > 0:
+ self.storeDom("memory/target-tot_pages", target * 1024)
+ self.info['platform']['actmem'] = str(target)
+
def setMemoryTarget(self, target):
"""Set the memory target of this domain.
@param target: In MiB.
@@ -2356,6 +2367,8 @@ class XendDomainInfo:
self.info['name_label'], self.domid, self.info['uuid'],
new_name, new_uuid)
self._unwatchVm()
+ if self.image:
+ self.image.destroyXenPaging()
self._releaseDevices()
# Remove existing vm node in xenstore
self._removeVm()
@@ -3035,6 +3048,9 @@ class XendDomainInfo:
self._createDevices()
+ if self.image:
+ self.image.createXenPaging()
+
self.image.cleanupTmpImages()
self.info['start_time'] = time.time()
@@ -3059,6 +3075,8 @@ class XendDomainInfo:
self.refresh_shutdown_lock.acquire()
try:
self.unwatchShutdown()
+ if self.image:
+ self.image.destroyXenPaging()
self._releaseDevices()
bootloader_tidy(self)
@@ -3143,6 +3161,7 @@ class XendDomainInfo:
self.image = image.create(self, self.info)
if self.image:
self.image.createDeviceModel(True)
+ self.image.createXenPaging()
self.console_port = console_port
self._storeDomDetails()
self._registerWatches()
@@ -3285,6 +3304,8 @@ class XendDomainInfo:
# could also fetch a parsed note from xenstore
fast = self.info.get_notes().get('SUSPEND_CANCEL') and 1 or 0
if not fast:
+ if self.image:
+ self.image.destroyXenPaging()
self._releaseDevices()
self.testDeviceComplete()
self.testvifsComplete()
@@ -3300,6 +3321,8 @@ class XendDomainInfo:
self._storeDomDetails()
self._createDevices()
+ if self.image:
+ self.image.createXenPaging()
log.debug("XendDomainInfo.resumeDomain: devices created")
xc.domain_resume(self.domid, fast)
Index: xen-4.4.0-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.4.0-testing/tools/python/xen/xend/image.py
@@ -122,6 +122,10 @@ class ImageHandler:
self.vm.permissionsVm("image/cmdline", { 'dom': self.vm.getDomid(), 'read': True } )
self.device_model = vmConfig['platform'].get('device_model')
+ self.actmem = str(vmConfig['platform'].get('actmem'))
+ self.xenpaging_file = str(vmConfig['platform'].get('xenpaging_file'))
+ self.xenpaging_extra = vmConfig['platform'].get('xenpaging_extra')
+ self.xenpaging_pid = None
self.smbios_firmware =(str(vmConfig['platform'].get('smbios_firmware')))
self.acpi_firmware =(str(vmConfig['platform'].get('acpi_firmware')))
@@ -394,6 +398,87 @@ class ImageHandler:
sentinel_fifos_inuse[sentinel_path_fifo] = 1
self.sentinel_path_fifo = sentinel_path_fifo
+ def createXenPaging(self):
+ if not self.vm.info.is_hvm():
+ return
+ if self.actmem == "0":
+ return
+ if self.xenpaging_pid:
+ return
+ xenpaging_bin = auxbin.pathTo("xenpaging")
+ args = [xenpaging_bin]
+ args = args + ([ "-f", "/var/lib/xen/xenpaging/%s.%d.paging" % (str(self.vm.info['name_label']), self.vm.getDomid())])
+ if self.xenpaging_extra:
+ args = args + (self.xenpaging_extra)
+ args = args + ([ "-d", "%d" % self.vm.getDomid()])
+ self.xenpaging_logfile = "/var/log/xen/xenpaging-%s.log" % str(self.vm.info['name_label'])
+ logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND|os.O_TRUNC
+ null = os.open("/dev/null", os.O_RDONLY)
+ try:
+ os.unlink(self.xenpaging_logfile)
+ except:
+ pass
+ logfd = os.open(self.xenpaging_logfile, logfile_mode, 0644)
+ sys.stderr.flush()
+ contract = osdep.prefork("%s:%d" % (self.vm.getName(), self.vm.getDomid()))
+ xenpaging_pid = os.fork()
+ if xenpaging_pid == 0: #child
+ try:
+ osdep.postfork(contract)
+ os.dup2(null, 0)
+ os.dup2(logfd, 1)
+ os.dup2(logfd, 2)
+ try:
+ env = dict(os.environ)
+ log.info("starting %s" % args)
+ os.execve(xenpaging_bin, args, env)
+ except Exception, e:
+ log.warn('failed to execute xenpaging: %s' % utils.exception_string(e))
+ os._exit(126)
+ except:
+ log.warn("starting xenpaging failed")
+ os._exit(127)
+ else:
+ osdep.postfork(contract, abandon=True)
+ self.xenpaging_pid = xenpaging_pid
+ os.close(null)
+ os.close(logfd)
+ self.vm.storeDom("xenpaging/xenpaging-pid", self.xenpaging_pid)
+ self.vm.storeDom("memory/target-tot_pages", int(self.actmem) * 1024)
+
+ def destroyXenPaging(self):
+ if self.actmem == "0":
+ return
+ if self.xenpaging_pid:
+ try:
+ os.kill(self.xenpaging_pid, signal.SIGHUP)
+ except OSError, exn:
+ log.exception(exn)
+ for i in xrange(100):
+ try:
+ (p, rv) = os.waitpid(self.xenpaging_pid, os.WNOHANG)
+ if p == self.xenpaging_pid:
+ break
+ except OSError:
+ # This is expected if Xend has been restarted within
+ # the life of this domain. In this case, we can kill
+ # the process, but we can't wait for it because it's
+ # not our child. We continue this loop, and after it is
+ # terminated make really sure the process is going away
+ # (SIGKILL).
+ pass
+ time.sleep(0.1)
+ else:
+ log.warning("xenpaging %d took more than 10s "
+ "to terminate: sending SIGKILL" % self.xenpaging_pid)
+ try:
+ os.kill(self.xenpaging_pid, signal.SIGKILL)
+ os.waitpid(self.xenpaging_pid, 0)
+ except OSError:
+ # This happens if the process doesn't exist.
+ pass
+ self.xenpaging_pid = None
+
def createDeviceModel(self, restore = False):
if self.device_model is None:
return
Index: xen-4.4.0-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.4.0-testing/tools/python/xen/xm/create.py
@@ -485,6 +485,18 @@ gopts.var('acpi_firmware', val='FILE',
fn=set_value, default=None,
use="Path to a file that contains extra ACPI firmware tables.")
+gopts.var('actmem', val='NUM',
+ fn=set_value, default='0',
+ use="Number of pages to swap.")
+
+gopts.var('xenpaging_file', val='PATH',
+ fn=set_value, default=None,
+ use="pagefile to use (optional)")
+
+gopts.var('xenpaging_extra', val='string1,string2',
+ fn=append_value, default=[],
+ use="additional args for xenpaging (optional)")
+
gopts.var('device_model', val='FILE',
fn=set_value, default=None,
use="Path to device model program.")
@@ -1059,6 +1071,9 @@ def configure_hvm(config_image, vals):
args = [ 'acpi', 'apic',
'boot',
'cpuid', 'cpuid_check',
+ 'actmem',
+ 'xenpaging_file',
+ 'xenpaging_extra',
'device_model', 'display',
'smbios_firmware', 'acpi_firmware',
'fda', 'fdb',
Index: xen-4.4.0-testing/tools/python/xen/xm/main.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/main.py
+++ xen-4.4.0-testing/tools/python/xen/xm/main.py
@@ -115,6 +115,8 @@ SUBCOMMAND_HELP = {
'Set the maximum amount reservation for a domain.'),
'mem-set' : ('<Domain> <Mem>',
'Set the current memory usage for a domain.'),
+ 'mem-swap-target' : ('<Domain> <Mem>',
+ 'Set the memory usage for a domain.'),
'migrate' : ('<Domain> <Host>',
'Migrate a domain to another machine.'),
'pause' : ('<Domain>', 'Pause execution of a domain.'),
@@ -1590,6 +1592,17 @@ def xm_mem_set(args):
mem_target = int_unit(args[1], 'm')
server.xend.domain.setMemoryTarget(dom, mem_target)
+def xm_mem_swap_target(args):
+ arg_check(args, "mem-swap-target", 2)
+
+ dom = args[0]
+
+ if serverType == SERVER_XEN_API:
+ err("xenapi not supported")
+ else:
+ swap_target = int_unit(args[1], 'm')
+ server.xend.domain.swaptarget_set(dom, swap_target)
+
def xm_usb_add(args):
arg_check(args, "usb-add", 2)
server.xend.domain.usb_add(args[0],args[1])
@@ -3796,6 +3809,7 @@ commands = {
# memory commands
"mem-max": xm_mem_max,
"mem-set": xm_mem_set,
+ "mem-swap-target": xm_mem_swap_target,
# cpu commands
"vcpu-pin": xm_vcpu_pin,
"vcpu-list": xm_vcpu_list,
Index: xen-4.4.0-testing/tools/python/xen/xm/xenapi_create.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/xenapi_create.py
+++ xen-4.4.0-testing/tools/python/xen/xm/xenapi_create.py
@@ -1046,6 +1046,9 @@ class sxp2xml:
'acpi',
'apic',
'boot',
+ 'actmem',
+ 'xenpaging_file',
+ 'xenpaging_extra',
'device_model',
'smbios_firmware',
'acpi_firmware',
++++++ xend-xm-create-xflag.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.4.0-testing/tools/python/xen/xm/create.py
@@ -36,7 +36,7 @@ from xen.xend.server.DevConstants import
from xen.util import blkif
from xen.util import vscsi_util
import xen.util.xsm.xsm as security
-from xen.xm.main import serverType, SERVER_XEN_API, get_single_vm
+from xen.xm.main import serverType, SERVER_XEN_API, SERVER_LEGACY_XMLRPC, get_single_vm
from xen.util import utils, auxbin
from xen.util.pci import dev_dict_to_sxp, \
parse_pci_name_extended, PciDeviceParseError
@@ -1465,7 +1465,7 @@ def main(argv):
except IOError, exn:
raise OptionError("Cannot read file %s: %s" % (config, exn[1]))
- if serverType == SERVER_XEN_API:
+ if serverType == SERVER_XEN_API or serverType == SERVER_LEGACY_XMLRPC:
from xen.xm.xenapi_create import sxp2xml
sxp2xml_inst = sxp2xml()
doc = sxp2xml_inst.convert_sxp_to_xml(config, transient=True)
@@ -1473,7 +1473,7 @@ def main(argv):
if opts.vals.dryrun and not opts.is_xml:
SXPPrettyPrint.prettyprint(config)
- if opts.vals.xmldryrun and serverType == SERVER_XEN_API:
+ if opts.vals.xmldryrun:
print doc.toprettyxml()
if opts.vals.dryrun or opts.vals.xmldryrun:
Index: xen-4.4.0-testing/tools/python/xen/xend/XendAPIConstants.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendAPIConstants.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendAPIConstants.py
@@ -45,8 +45,10 @@ XEN_API_ON_NORMAL_EXIT = [
XEN_API_ON_CRASH_BEHAVIOUR = [
'destroy',
'coredump_and_destroy',
+ 'coredump_destroy',
'restart',
'coredump_and_restart',
+ 'coredump_restart',
'preserve',
'rename_restart'
]
++++++ xend-xm-reboot-fix.patch ++++++
References: bnc#840997
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -435,7 +435,17 @@ class XendDomainInfo:
if i != 0:
self.vmpath = self.vmpath + '-' + str(i)
try:
- if self._readVm("uuid"):
+ # On reboot, the old VM may not be completely gone causing
+ # duplicate VMs to appear one of which has '-1' appended to
+ # the uuid. This can lead to VM corruption.
+ timeout = 0
+ while timeout < 5:
+ if self._readVm("uuid"):
+ time.sleep(0.1)
+ timeout += 1
+ else:
+ break
+ if timeout >= 5:
self.vmpath = None
i = i + 1
except:
++++++ xend-xm-save-check-file.patch ++++++
Index: xen-4.4.0-testing/tools/python/xen/xend/XendAPI.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendAPI.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendAPI.py
@@ -1941,10 +1941,10 @@ class XendAPI(object):
bool(live), port, node, ssl, bool(chs))
return xen_api_success_void()
- def VM_save(self, _, vm_ref, dest, checkpoint):
+ def VM_save(self, _, vm_ref, dest, checkpoint, force):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
- xendom.domain_save(xeninfo.getDomid(), dest, checkpoint)
+ xendom.domain_save(xeninfo.getDomid(), dest, checkpoint, force)
return xen_api_success_void()
def VM_restore(self, _, src, paused):
Index: xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xend/XendDomain.py
+++ xen-4.4.0-testing/tools/python/xen/xend/XendDomain.py
@@ -1505,7 +1505,7 @@ class XendDomain:
pass
sock.close()
- def domain_save(self, domid, dst, checkpoint=False):
+ def domain_save(self, domid, dst, checkpoint=False, force=False):
"""Start saving a domain to file.
@param domid: Domain ID or Name
@@ -1521,6 +1521,9 @@ class XendDomain:
if not dominfo:
raise XendInvalidDomain(str(domid))
+ if os.access(dst, os.F_OK) and not force:
+ raise XendError("Save file:%s exist!\n" % dst)
+
if dominfo.getDomid() == DOM0_ID:
raise XendError("Cannot save privileged domain %s" % str(domid))
if dominfo._stateGet() != DOM_STATE_RUNNING:
Index: xen-4.4.0-testing/tools/python/xen/xm/main.py
===================================================================
--- xen-4.4.0-testing.orig/tools/python/xen/xm/main.py
+++ xen-4.4.0-testing/tools/python/xen/xm/main.py
@@ -122,7 +122,7 @@ SUBCOMMAND_HELP = {
'reset' : ('<Domain>', 'Reset a domain.'),
'restore' : ('<CheckpointFile> [-p]',
'Restore a domain from a saved state.'),
- 'save' : ('[-c] <Domain> <CheckpointFile>',
+ 'save' : ('[-c|-f] <Domain> <CheckpointFile>',
'Save a domain state to restore later.'),
'shutdown' : ('<Domain> [-waRH]', 'Shutdown a domain.'),
'top' : ('', 'Monitor a host and the domains in real time.'),
@@ -345,6 +345,7 @@ SUBCOMMAND_OPTIONS = {
),
'save': (
('-c', '--checkpoint', 'Leave domain running after creating snapshot'),
+ ('-f', '--force', 'Force to overwrite exist file'),
),
'restore': (
('-p', '--paused', 'Do not unpause domain after restoring it'),
@@ -868,18 +869,21 @@ def xm_event_monitor(args):
def xm_save(args):
- arg_check(args, "save", 2, 3)
+ arg_check(args, "save", 2, 4)
try:
- (options, params) = getopt.gnu_getopt(args, 'c', ['checkpoint'])
+ (options, params) = getopt.gnu_getopt(args, 'cf', ['checkpoint', 'force'])
except getopt.GetoptError, opterr:
err(opterr)
usage('save')
checkpoint = False
+ force = False
for (k, v) in options:
if k in ['-c', '--checkpoint']:
checkpoint = True
+ if k in ['-f', '--force']:
+ force = True
if len(params) != 2:
err("Wrong number of parameters")
@@ -893,9 +897,9 @@ def xm_save(args):
sys.exit(1)
if serverType == SERVER_XEN_API:
- server.xenapi.VM.save(get_single_vm(dom), savefile, checkpoint)
+ server.xenapi.VM.save(get_single_vm(dom), savefile, checkpoint, force)
else:
- server.xend.domain.save(dom, savefile, checkpoint)
+ server.xend.domain.save(dom, savefile, checkpoint, force)
def xm_restore(args):
arg_check(args, "restore", 1, 2)
++++++ xend-xsa153.patch ++++++
References: bsc#951845 XSA-153 - This is the xend version
From 27593ec62bdad8621df910931349d964a6dbaa8c Mon Sep 17 00:00:00 2001
From: Ian Jackson
Date: Wed, 21 Oct 2015 16:18:30 +0100
Subject: [PATCH XSA-153 v3] libxl: adjust PoD target by memory fudge, too
PoD guests need to balloon at least as far as required by PoD, or risk
crashing. Currently they don't necessarily know what the right value
is, because our memory accounting is (at the very least) confusing.
Apply the memory limit fudge factor to the in-hypervisor PoD memory
target, too. This will increase the size of the guest's PoD cache by
the fudge factor LIBXL_MAXMEM_CONSTANT (currently 1Mby). This ensures
that even with a slightly-off balloon driver, the guest will be
stable even under memory pressure.
There are two call sites of xc_domain_set_pod_target that need fixing:
The one in libxl_set_memory_target is straightforward.
The one in xc_hvm_build_x86.c:setup_guest is more awkward. Simply
setting the PoD target differently does not work because the various
amounts of memory during domain construction no longer match up.
Instead, we adjust the guest memory target in xenstore (but only for
PoD guests).
This introduces a 1Mby discrepancy between the balloon target of a PoD
guest at boot, and the target set by an apparently-equivalent `xl
mem-set' (or similar) later. This approach is low-risk for a security
fix but we need to fix this up properly in xen.git#staging and
probably also in stable trees.
This is XSA-153.
Index: xen-4.4.3-testing/tools/python/xen/lowlevel/xc/xc.c
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/lowlevel/xc/xc.c
+++ xen-4.4.3-testing/tools/python/xen/lowlevel/xc/xc.c
@@ -1678,7 +1678,8 @@ static PyObject *pyxc_domain_set_target_
if (!PyArg_ParseTuple(args, "ii", &dom, &mem_kb))
return NULL;
- mem_pages = mem_kb / 4;
+ /* bsc#951845 - CVE-2015-7972 XSA-153 */
+ mem_pages = (mem_kb + 1024) / 4;
if (xc_domain_set_pod_target(self->xc_handle, dom, mem_pages,
NULL, NULL, NULL) != 0)
Index: xen-4.4.3-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.4.3-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.4.3-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -3056,6 +3056,10 @@ class XendDomainInfo:
self.info['start_time'] = time.time()
self._stateSet(DOM_STATE_RUNNING)
+
+ if self.pod_enabled:
+ # bsc#951845 - CVE-2015-7972 XSA-153
+ self.info['memory_dynamic_max'] = self.info['memory_dynamic_max'] - 1024
except VmError, exn:
log.exception("XendDomainInfo.initDomain: exception occurred")
if self.image:
++++++ xend.service ++++++
[Unit]
Description=Xend - Starts and stops the Xen management daemon
Before=libvirtd.service libvirt-guests.service
ConditionPathExists=/proc/xen
[Service]
Type=forking
PIDFile=/var/run/xend.pid
Environment=HOME=/root
ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
ExecStart=/usr/sbin/xend start
[Install]
WantedBy=multi-user.target
++++++ xendomains.service ++++++
[Unit]
Description=Xendomains - start and stop Xen VMs on boot and shutdown
After=xencommons.service network.target
ConditionPathExists=/proc/xen
[Service]
Type=oneshot
RemainAfterExit=true
ExecStartPre=/bin/grep -q control_d /proc/xen/capabilities
ExecStart=-/etc/init.d/xendomains start
ExecStop=/etc/init.d/xendomains stop
[Install]
WantedBy=multi-user.target
++++++ xenpaging.doc.patch ++++++
---
docs/misc/xenpaging.txt | 49 +++++++++++++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 15 deletions(-)
Index: xen-4.2.0-testing/docs/misc/xenpaging.txt
===================================================================
--- xen-4.2.0-testing.orig/docs/misc/xenpaging.txt
+++ xen-4.2.0-testing/docs/misc/xenpaging.txt
@@ -22,22 +22,41 @@ functionality.
Usage:
-Up to now xenpaging is not integrated into libxl/xend, so it has to be
-started manually for each guest.
+Up to now xenpaging is only integrated into xm/xend.
-Once the guest is running, run xenpaging with the guest_id and the path
-to the pagefile:
-
- /usr/lib/xen/bin/xenpaging -f /path/to/page_file -d dom_id &
-
-Once xenpaging runs it needs a memory target, which is the memory
-footprint of the guest. This value (in KiB) must be written manually to
-xenstore. The following example sets the target to 512MB:
-
- xenstore-write /local/domain//memory/target-tot_pages $((1024*512))
-
-Now xenpaging tries to page-out as many pages to keep the overall memory
-footprint of the guest at 512MB.
+To enable xenpaging for a guest add the option 'actmem=' to the guests
+config file and run 'xm new ' to make the changes
+active. actmem= takes the amount of memory in MB which a guest is
+allowed to use at a given time. Everything above this limit will be
+paged out. This paging is transparent to the guest.
+
+Example:
+ memory=4096
+ actmem=1024
+In this example a guest gets the impression it has 4GB of memory and
+the guest OS has to configure itself for this amount of memory. But
+xenpaging will page-out 3072MB, leaving only 1024MB active at a time.
+
+At runtime the configured value of actmem= can be changed with the "xm
+mem-swap-target" command.
+ xm mem-swap-target 512
+
+Additional cmdline options for the xenpaging binary can be specified
+with the xenpaging_extra= config file option:
+
+ xenpaging_extra=[ '-f', '/dev/shm/pagefile-guest_name', '-v' ]
+
+To get a list of available options, run /usr/lib/xen/bin/xenpaging -h:
+
+ xenpaging [options] -f <pagefile> -d
+
+options:
+ -d <domid> --domain=<domid> numerical domain_id of guest. This option is required.
+ -f <file> --pagefile=<file> pagefile to use. This option is required.
+ -m --max_memkb= maximum amount of memory to handle.
+ -r <num> --mru_size=<num> number of paged-in pages to keep in memory.
+ -v --verbose enable debug output.
+ -h --help this output.
Todo:
- integrate xenpaging into libxl
++++++ xenpaging.qemu.flush-cache.patch ++++++
Subject: xenpaging/qemu-dm: add command to flush buffer cache.
Add support for a xenstore dm command to flush qemu's buffer cache.
qemu will just keep mapping pages and not release them, which causes problems
for the memory pager (since the page is mapped, it won't get paged out). When
the pager has trouble finding a page to page out, it asks qemu to flush its
buffer, which releases all the page mappings. This makes it possible to find
pages to swap out agian.
Already-Signed-off-by: Patrick Colp
Signed-off-by: Olaf Hering
---
tools/qemu-xen-traditional-dir-remote/xenstore.c | 3 +++
1 file changed, 3 insertions(+)
Index: xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.2.3-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.2.3-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -1020,6 +1020,9 @@ static void xenstore_process_dm_command_
do_pci_add(par);
free(par);
#endif
+ } else if (!strncmp(command, "flush-cache", len)) {
+ fprintf(logfile, "dm-command: flush caches\n");
+ qemu_invalidate_map_cache();
} else {
fprintf(logfile, "dm-command: unknown command\"%*s\"\n", len, command);
}
++++++ xl-check-for-libvirt-managed-domain.patch ++++++
Index: xen-4.4.0-testing/tools/libxl/xl.c
===================================================================
--- xen-4.4.0-testing.orig/tools/libxl/xl.c
+++ xen-4.4.0-testing/tools/libxl/xl.c
@@ -282,6 +282,32 @@ static void xl_ctx_free(void)
}
}
+/*
+ Return 0 if domain is managed by libvirt
+*/
+static int xl_lookup_libvirt_managed_domain(int argc, char **argv)
+{
+ uint32_t domid;
+ uint8_t *t_data;
+ char *domname;
+ int i, rc, t_len;
+
+ for (i=0; imodifies && !dryrun_only) {
+ if (!force_execution) {
+ if (!xl_lookup_libvirt_managed_domain(argc, argv)) {
+ fprintf(stderr,
+"Warning: This domain is managed by libvirt. Using xl commands to modify this\n"
+"domain will result in errors when virsh or virt-manager is used.\n"
+"Please use only virsh or virt-manager to manage this domain.\n\n"
+"(This check can be overridden with the -f option.)\n"
+ );
+ ret = 1;
+ goto xit;
+ }
+ }
for (int i = 0; i < sizeof(locks)/sizeof(locks[0]); i++) {
if (!access(locks[i], F_OK) && !force_execution) {
fprintf(stderr,
++++++ xl-conf-default-bridge.patch ++++++
Index: xen-4.4.0-testing/tools/examples/xl.conf
===================================================================
--- xen-4.4.0-testing.orig/tools/examples/xl.conf
+++ xen-4.4.0-testing/tools/examples/xl.conf
@@ -30,7 +30,7 @@
#vif.default.script="vif-bridge"
# default bridge device to use with vif-bridge hotplug scripts
-#vif.default.bridge="xenbr0"
+vif.default.bridge="br0"
# Reserve a claim of memory when launching a guest. This guarantees immediate
# feedback whether the guest can be launched due to memory exhaustion
++++++ xl-coredump-file-location.patch ++++++
xl: change default dump directory
Upstream xl uses /var/xen/dump/ as the default directory for
domain core dumps. This patch changes the path to the more
FHS-friendly location of /var/lib/xen/dump/, which was also
the path used in SLE11.
See bsc#900292
Index: xen-4.4.2-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.4.2-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.4.2-testing/tools/libxl/xl_cmdimpl.c
@@ -1826,7 +1826,7 @@ static int handle_domain_death(uint32_t
char *corefile;
int rc;
- if (asprintf(&corefile, "/var/xen/dump/%s", d_config->c_info.name) < 0) {
+ if (asprintf(&corefile, "/var/lib/xen/dump/%s", d_config->c_info.name) < 0) {
LOG("failed to construct core dump path");
} else {
LOG("dumping core to %s", corefile);
++++++ xmclone.sh ++++++
++++ 795 lines (skipped)
++++++ xmexample.disks ++++++
# A VM's disks can be stored in a variety of ways.
# Here are some examples:
disk = [
# Block device
'phy:/dev/hdb,xvda,w',
# Raw format, accessed via loopback
'file:/var/lib/xen/images/disk-example/disk0,xvdb,w',
# Raw format, accessed via blocktap
'tap:aio:/var/lib/xen/images/disk-example/disk0,xvdc,w',
# QCOW format, accessed via blocktap
'tap:qcow:/var/lib/xen/images/disk-example/disk0.qcow,xvdd,w',
# NBD (network block device): IP and port are separated by space
'nbd:192.168.0.1 20004,xvde,w',
# iSCSI: The usual colon is replaced with '@'
'iscsi:iqn.2006-09.de.suse@0ac47ee2-216e-452a-a341-a12624cd0225,xvdf,w',
# Fibre Channel N_Port ID Virtualization
'npiv:210400e08b80c40f,xvdg,w' ]
# Remaining settings for the example VM:
name="disk-example"
memory=512
vcpus=1
on_crash="destroy"
on_poweroff="destroy"
on_reboot="restart"
localtime=0
builder="linux"
bootloader="/usr/lib/xen/boot/domUloader.py"
bootargs="--entry=xvda2:/boot/vmlinuz-xen,/boot/initrd-xen"
vif=[ 'mac=00:16:3e:00:01:02,bridge=xenbr0' ]
vfb=['type=vnc,vncunused=1']
++++++ xmexample.domUloader ++++++
# This is a bootloader used to boot paravirtualized domains. You can optionally
# plug in a different boot loader here, e.g., pygrub. There is usually no
# reason to change this. Don't explicitly specify kernel and ramdisk if you use
# a bootloader.
bootloader="/usr/lib/xen/boot/domUloader.py"
# The domUloader will pull the specified kernel and initrd out of the domU's
# disk, and use that to boot. This is easier to manage, compared to manually
# keeping a copy of the kernel and initrd in sync in dom0's filesystem and
# pointing to them with the "kernel" and "ramdisk" parameters. Syntax is
# "VDEV:KERNEL,INITRD", where VDEV is the block device (from domU's point of
# view) within which KERNEL and INITRD can be found.
bootentry = "hda1:/boot/vmlinuz-xen,/boot/initrd-xen"
# Remaining settings for the example VM:
name="domUloader-example"
memory=512
vcpus=1
on_crash="destroy"
on_poweroff="destroy"
on_reboot="restart"
localtime=0
builder="linux"
bootargs="--entry=xvda2:/boot/vmlinuz-xen,/boot/initrd-xen"
disk=[ 'file:/var/lib/xen/images/domUloader-example/disk0,xvda,w' ]
vif=[ 'mac=00:16:3e:00:01:02,bridge=xenbr0' ]
vfb=['type=vnc,vncunused=1']
++++++ xnloader.py ++++++
# NetWare-specific operations
#
# Copyright (c) 2013 Suse Linux Products.
# Author: Charles Arnold
#
# This software may be freely redistributed under the terms of the GNU
# general public license.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# Binary patching of xnloader.sys
# For launching NetWare on Xen 4.2 and newer
import os, sys, base64
CODE_OFFSET=0x49F5
NUMBER_OF_CODE_BYTES=17
ORIGINAL_CODE="BA00080000C786FC1F0000FFFFFFFF31C9"
PATCHED_CODE="BAF8070000834C961CFFB9080000009090"
XNLOADER_SYS_MD5SUM="eb76cce2a2d45928ea2bf26e01430af2"
def patch_netware_loader(loader):
"""Open the given xnloader.sys file and patch the relevant code hunk."""
# domUloader calls this with all kernels so perhaps this is not the NetWare loader
md5sum_cmd = 'md5sum ' + loader
p = os.popen(md5sum_cmd)
sum = p.read().split()[0]
p.close()
if sum != XNLOADER_SYS_MD5SUM:
return
try:
fd = os.open(loader, os.O_RDWR)
except Exception, e:
print >>sys.stderr, e
raise
# Validate minimum size for I/O
stat = os.fstat(fd)
if stat.st_size < CODE_OFFSET+NUMBER_OF_CODE_BYTES:
os.close(fd)
return
# Seek to location of code hunk
os.lseek(fd, CODE_OFFSET, os.SEEK_SET)
# Read code bytes at offset
buf = os.read(fd, NUMBER_OF_CODE_BYTES)
code_as_hex = base64.b16encode(buf)
if code_as_hex == ORIGINAL_CODE:
# Seek back to start location of the code hunk
os.lseek(fd, CODE_OFFSET, os.SEEK_SET)
# Convert the PATCHED_CODE string to raw binary
code_as_bin = base64.b16decode(PATCHED_CODE)
# Write the patched code
os.write(fd, code_as_bin)
os.close(fd)
++++++ xsa140-qemut-1.patch ++++++
References: bsc#939712 XSA-140
From 5e0c290415b9d57077a86e70c8e6a058868334d3 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi
Date: Wed, 15 Jul 2015 18:16:58 +0100
Subject: [PATCH 1/7] rtl8139: avoid nested ifs in IP header parsing
Transmit offload needs to parse packet headers. If header fields have
unexpected values the offload processing is skipped.
The code currently uses nested ifs because there is relatively little
input validation. The next patches will add missing input validation
and a goto label is more appropriate to avoid deep if statement nesting.
Signed-off-by: Stefan Hajnoczi
---
hw/rtl8139.c | 41 ++++++++++++++++++++++-------------------
1 file changed, 22 insertions(+), 19 deletions(-)
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
@@ -2113,26 +2113,30 @@ static int rtl8139_cplus_transmit_one(RT
size_t eth_payload_len = 0;
int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
- if (proto == ETH_P_IP)
+ if (proto != ETH_P_IP)
{
- DEBUG_PRINT(("RTL8139: +++ C+ mode has IP packet\n"));
+ goto skip_offload;
+ }
- /* not aligned */
- eth_payload_data = saved_buffer + ETH_HLEN;
- eth_payload_len = saved_size - ETH_HLEN;
-
- ip = (ip_header*)eth_payload_data;
-
- if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
- DEBUG_PRINT(("RTL8139: +++ C+ mode packet has bad IP version %d expected %d\n", IP_HEADER_VERSION(ip), IP_HEADER_VERSION_4));
- ip = NULL;
- } else {
- hlen = IP_HEADER_LENGTH(ip);
- ip_protocol = ip->ip_p;
- ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
- }
+ DEBUG_PRINT(("RTL8139: +++ C+ mode has IP packet\n"));
+
+ /* not aligned */
+ eth_payload_data = saved_buffer + ETH_HLEN;
+ eth_payload_len = saved_size - ETH_HLEN;
+
+ ip = (ip_header*)eth_payload_data;
+
+ if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
+ DEBUG_PRINT(("RTL8139: +++ C+ mode packet has bad IP version %d "
+ "expected %d\n", IP_HEADER_VERSION(ip),
+ IP_HEADER_VERSION_4));
+ goto skip_offload;
}
+ hlen = IP_HEADER_LENGTH(ip);
+ ip_protocol = ip->ip_p;
+ ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
+
if (ip)
{
if (txdw0 & CP_TX_IPCS)
@@ -2315,6 +2319,7 @@ static int rtl8139_cplus_transmit_one(RT
}
}
+skip_offload:
/* update tally counter */
++s->tally_counters.TxOk;
++++++ xsa140-qemut-2.patch ++++++
References: bsc#939712 XSA-140
From 2d7d80e8dc160904fa7276cc05da26c062a50066 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi
Date: Wed, 15 Jul 2015 18:16:59 +0100
Subject: [PATCH 2/7] rtl8139: drop tautologous if (ip) {...} statement
The previous patch stopped using the ip pointer as an indicator that the
IP header is present. When we reach the if (ip) {...} statement we know
ip is always non-NULL.
Remove the if statement to reduce nesting.
Signed-off-by: Stefan Hajnoczi
---
hw/rtl8139.c | 305 +++++++++++++++++++++++++++----------------------------
1 file changed, 151 insertions(+), 154 deletions(-)
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
@@ -2137,187 +2137,184 @@ static int rtl8139_cplus_transmit_one(RT
ip_protocol = ip->ip_p;
ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
- if (ip)
+ if (txdw0 & CP_TX_IPCS)
{
- if (txdw0 & CP_TX_IPCS)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n"));
+ DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n"));
- if (hleneth_payload_len) {/* min header length */
- /* bad packet header len */
- /* or packet too short */
- }
- else
- {
- ip->ip_sum = 0;
- ip->ip_sum = ip_checksum(ip, hlen);
- DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
- }
+ if (hleneth_payload_len) {/* min header length */
+ /* bad packet header len */
+ /* or packet too short */
}
-
- if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
+ else
{
-#if defined (DEBUG_RTL8139)
- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
-#endif
- DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n",
- ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss));
-
- int tcp_send_offset = 0;
- int send_count = 0;
+ ip->ip_sum = 0;
+ ip->ip_sum = ip_checksum(ip, hlen);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
+ }
+ }
- /* maximum IP header length is 60 bytes */
- uint8_t saved_ip_header[60];
+ if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
+ {
+ int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
- /* save IP header template; data area is used in tcp checksum calculation */
- memcpy(saved_ip_header, eth_payload_data, hlen);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n",
+ ETH_MTU, ip_data_len, saved_size - ETH_HLEN, large_send_mss));
- /* a placeholder for checksum calculation routine in tcp case */
- uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
- // size_t data_to_checksum_len = eth_payload_len - hlen + 12;
+ int tcp_send_offset = 0;
+ int send_count = 0;
- /* pointer to TCP header */
- tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
+ /* maximum IP header length is 60 bytes */
+ uint8_t saved_ip_header[60];
- int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
+ /* save IP header template; data area is used in tcp checksum calculation */
+ memcpy(saved_ip_header, eth_payload_data, hlen);
- /* ETH_MTU = ip header len + tcp header len + payload */
- int tcp_data_len = ip_data_len - tcp_hlen;
- int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
+ /* a placeholder for checksum calculation routine in tcp case */
+ uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
+ // size_t data_to_checksum_len = eth_payload_len - hlen + 12;
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n",
- ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size));
+ /* pointer to TCP header */
+ tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
- /* note the cycle below overwrites IP header data,
- but restores it from saved_ip_header before sending packet */
+ int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
- int is_last_frame = 0;
+ /* ETH_MTU = ip header len + tcp header len + payload */
+ int tcp_data_len = ip_data_len - tcp_hlen;
+ int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
- for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
- {
- uint16_t chunk_size = tcp_chunk_size;
+ DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP data len %d TCP hlen %d TCP data len %d TCP chunk size %d\n",
+ ip_data_len, tcp_hlen, tcp_data_len, tcp_chunk_size));
- /* check if this is the last frame */
- if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
- {
- is_last_frame = 1;
- chunk_size = tcp_data_len - tcp_send_offset;
- }
+ /* note the cycle below overwrites IP header data,
+ but restores it from saved_ip_header before sending packet */
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq)));
+ int is_last_frame = 0;
- /* add 4 TCP pseudoheader fields */
- /* copy IP source and destination fields */
- memcpy(data_to_checksum, saved_ip_header + 12, 8);
+ for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)
+ {
+ uint16_t chunk_size = tcp_chunk_size;
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size));
+ /* check if this is the last frame */
+ if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)
+ {
+ is_last_frame = 1;
+ chunk_size = tcp_data_len - tcp_send_offset;
+ }
- if (tcp_send_offset)
- {
- memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
- }
+ DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP seqno %08x\n", be32_to_cpu(p_tcp_hdr->th_seq)));
- /* keep PUSH and FIN flags only for the last frame */
- if (!is_last_frame)
- {
- TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
- }
+ /* add 4 TCP pseudoheader fields */
+ /* copy IP source and destination fields */
+ memcpy(data_to_checksum, saved_ip_header + 12, 8);
- /* recalculate TCP checksum */
- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
- p_tcpip_hdr->zeros = 0;
- p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
- p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode TSO calculating TCP checksum for packet with %d bytes data\n", tcp_hlen + chunk_size));
- p_tcp_hdr->th_sum = 0;
+ if (tcp_send_offset)
+ {
+ DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len));
+ memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);
+ }
- int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum));
+ /* keep PUSH and FIN flags only for the last frame */
+ if (!is_last_frame)
+ {
+ TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);
+ }
- p_tcp_hdr->th_sum = tcp_checksum;
+ /* recalculate TCP checksum */
+ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
+ p_tcpip_hdr->zeros = 0;
+ p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
+ p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);
- /* restore IP header */
- memcpy(eth_payload_data, saved_ip_header, hlen);
+ p_tcp_hdr->th_sum = 0;
- /* set IP data length and recalculate IP checksum */
- ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
+ int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode TSO TCP checksum %04x\n", tcp_checksum));
- /* increment IP id for subsequent frames */
- ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
+ p_tcp_hdr->th_sum = tcp_checksum;
- ip->ip_sum = 0;
- ip->ip_sum = ip_checksum(eth_payload_data, hlen);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
+ /* restore IP header */
+ memcpy(eth_payload_data, saved_ip_header, hlen);
- int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
- DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size));
- rtl8139_transfer_frame(s, saved_buffer, tso_send_size, 0);
+ /* set IP data length and recalculate IP checksum */
+ ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);
- /* add transferred count to TCP sequence number */
- p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
- ++send_count;
- }
+ /* increment IP id for subsequent frames */
+ ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));
- /* Stop sending this frame */
- saved_size = 0;
+ ip->ip_sum = 0;
+ ip->ip_sum = ip_checksum(eth_payload_data, hlen);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode TSO IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
+
+ int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;
+ DEBUG_PRINT(("RTL8139: +++ C+ mode TSO transferring packet size %d\n", tso_send_size));
+ rtl8139_transfer_frame(s, saved_buffer, tso_send_size, 0);
+
+ /* add transferred count to TCP sequence number */
+ p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));
+ ++send_count;
}
- else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n"));
- /* maximum IP header length is 60 bytes */
- uint8_t saved_ip_header[60];
- memcpy(saved_ip_header, eth_payload_data, hlen);
+ /* Stop sending this frame */
+ saved_size = 0;
+ }
+ else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))
+ {
+ DEBUG_PRINT(("RTL8139: +++ C+ mode need TCP or UDP checksum\n"));
- uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
- // size_t data_to_checksum_len = eth_payload_len - hlen + 12;
+ /* maximum IP header length is 60 bytes */
+ uint8_t saved_ip_header[60];
+ memcpy(saved_ip_header, eth_payload_data, hlen);
- /* add 4 TCP pseudoheader fields */
- /* copy IP source and destination fields */
- memcpy(data_to_checksum, saved_ip_header + 12, 8);
+ uint8_t *data_to_checksum = eth_payload_data + hlen - 12;
+ // size_t data_to_checksum_len = eth_payload_len - hlen + 12;
- if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len));
+ /* add 4 TCP pseudoheader fields */
+ /* copy IP source and destination fields */
+ memcpy(data_to_checksum, saved_ip_header + 12, 8);
- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
- p_tcpip_hdr->zeros = 0;
- p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
- p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
+ if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)
+ {
+ DEBUG_PRINT(("RTL8139: +++ C+ mode calculating TCP checksum for packet with %d bytes data\n", ip_data_len));
- tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
+ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;
+ p_tcpip_hdr->zeros = 0;
+ p_tcpip_hdr->ip_proto = IP_PROTO_TCP;
+ p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
- p_tcp_hdr->th_sum = 0;
+ tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);
- int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum));
+ p_tcp_hdr->th_sum = 0;
- p_tcp_hdr->th_sum = tcp_checksum;
- }
- else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
- {
- DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len));
+ int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode TCP checksum %04x\n", tcp_checksum));
- ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
- p_udpip_hdr->zeros = 0;
- p_udpip_hdr->ip_proto = IP_PROTO_UDP;
- p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
+ p_tcp_hdr->th_sum = tcp_checksum;
+ }
+ else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)
+ {
+ DEBUG_PRINT(("RTL8139: +++ C+ mode calculating UDP checksum for packet with %d bytes data\n", ip_data_len));
- udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
+ ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;
+ p_udpip_hdr->zeros = 0;
+ p_udpip_hdr->ip_proto = IP_PROTO_UDP;
+ p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);
- p_udp_hdr->uh_sum = 0;
+ udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);
- int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
- DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum));
+ p_udp_hdr->uh_sum = 0;
- p_udp_hdr->uh_sum = udp_checksum;
- }
+ int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode UDP checksum %04x\n", udp_checksum));
- /* restore IP header */
- memcpy(eth_payload_data, saved_ip_header, hlen);
+ p_udp_hdr->uh_sum = udp_checksum;
}
+
+ /* restore IP header */
+ memcpy(eth_payload_data, saved_ip_header, hlen);
}
- }
+ }
skip_offload:
/* update tally counter */
++++++ xsa140-qemut-3.patch ++++++
References: bsc#939712 XSA-140
From 043d28507ef7c5fdc34866f5e3b27a72bd0cd072 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi
Date: Wed, 15 Jul 2015 18:17:00 +0100
Subject: [PATCH 3/7] rtl8139: skip offload on short Ethernet/IP header
Transmit offload features access Ethernet and IP headers the packet. If
the packet is too short we must not attempt to access header fields:
int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
...
eth_payload_data = saved_buffer + ETH_HLEN;
...
ip = (ip_header*)eth_payload_data;
if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
Signed-off-by: Stefan Hajnoczi
---
hw/rtl8139.c | 5 +++++
1 file changed, 5 insertions(+)
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
@@ -2103,6 +2103,11 @@ static int rtl8139_cplus_transmit_one(RT
#define ETH_HLEN 14
#define ETH_MTU 1500
+ /* Large enough for Ethernet and IP headers? */
+ if (saved_size < ETH_HLEN + sizeof(ip_header)) {
+ goto skip_offload;
+ }
+
/* ip packet header */
ip_header *ip = 0;
int hlen = 0;
++++++ xsa140-qemut-4.patch ++++++
References: bsc#939712 XSA-140
From 5a75d242fe019d05b46ef9bc330a6892525c84a7 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi
Date: Wed, 15 Jul 2015 18:17:01 +0100
Subject: [PATCH 4/7] rtl8139: check IP Header Length field
The IP Header Length field was only checked in the IP checksum case, but
is used in other cases too.
Signed-off-by: Stefan Hajnoczi
---
hw/rtl8139.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
@@ -2139,6 +2139,10 @@ static int rtl8139_cplus_transmit_one(RT
}
hlen = IP_HEADER_LENGTH(ip);
+ if (hlen < sizeof(ip_header) || hlen > eth_payload_len) {
+ goto skip_offload;
+ }
+
ip_protocol = ip->ip_p;
ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
@@ -2146,16 +2150,9 @@ static int rtl8139_cplus_transmit_one(RT
{
DEBUG_PRINT(("RTL8139: +++ C+ mode need IP checksum\n"));
- if (hleneth_payload_len) {/* min header length */
- /* bad packet header len */
- /* or packet too short */
- }
- else
- {
- ip->ip_sum = 0;
- ip->ip_sum = ip_checksum(ip, hlen);
- DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
- }
+ ip->ip_sum = 0;
+ ip->ip_sum = ip_checksum(ip, hlen);
+ DEBUG_PRINT(("RTL8139: +++ C+ mode IP header len=%d checksum=%04x\n", hlen, ip->ip_sum));
}
if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
++++++ xsa140-qemut-5.patch ++++++
References: bsc#939712 XSA-140
From 6c79ea275d72bc1fd88bdcf1e7d231b2c9c865de Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi
Date: Wed, 15 Jul 2015 18:17:02 +0100
Subject: [PATCH 5/7] rtl8139: check IP Total Length field
The IP Total Length field includes the IP header and data. Make sure it
is valid and does not exceed the Ethernet payload size.
Signed-off-by: Stefan Hajnoczi
---
hw/rtl8139.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
@@ -2144,7 +2144,12 @@ static int rtl8139_cplus_transmit_one(RT
}
ip_protocol = ip->ip_p;
- ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
+
+ ip_data_len = be16_to_cpu(ip->ip_len);
+ if (ip_data_len < hlen || ip_data_len > eth_payload_len) {
+ goto skip_offload;
+ }
+ ip_data_len -= hlen;
if (txdw0 & CP_TX_IPCS)
{
++++++ xsa140-qemut-6.patch ++++++
References: bsc#939712 XSA-140
From 30aa7be430e7c982e9163f3bcc745d3aa57b6aa4 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi
Date: Wed, 15 Jul 2015 18:17:03 +0100
Subject: [PATCH 6/7] rtl8139: skip offload on short TCP header
TCP Large Segment Offload accesses the TCP header in the packet. If the
packet is too short we must not attempt to access header fields:
tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);
int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
Signed-off-by: Stefan Hajnoczi
---
hw/rtl8139.c | 5 +++++
1 file changed, 5 insertions(+)
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
@@ -2162,6 +2162,11 @@ static int rtl8139_cplus_transmit_one(RT
if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)
{
+ /* Large enough for the TCP header? */
+ if (ip_data_len < sizeof(tcp_header)) {
+ goto skip_offload;
+ }
+
int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;
DEBUG_PRINT(("RTL8139: +++ C+ mode offloaded task TSO MTU=%d IP data %d frame data %d specified MSS=%d\n",
++++++ xsa140-qemut-7.patch ++++++
References: bsc#939712 XSA-140
From 9a084807bf6ca7c16d997a236d304111894a6539 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi
Date: Wed, 15 Jul 2015 18:17:04 +0100
Subject: [PATCH 7/7] rtl8139: check TCP Data Offset field
The TCP Data Offset field contains the length of the header. Make sure
it is valid and does not exceed the IP data length.
Signed-off-by: Stefan Hajnoczi
---
hw/rtl8139.c | 5 +++++
1 file changed, 5 insertions(+)
Index: xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
===================================================================
--- xen-4.4.2-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
+++ xen-4.4.2-testing/tools/qemu-xen-traditional-dir-remote/hw/rtl8139.c
@@ -2190,6 +2190,11 @@ static int rtl8139_cplus_transmit_one(RT
int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);
+ /* Invalid TCP data offset? */
+ if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) {
+ goto skip_offload;
+ }
+
/* ETH_MTU = ip header len + tcp header len + payload */
int tcp_data_len = ip_data_len - tcp_hlen;
int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;
++++++ xsa153-libxl.patch ++++++
From 27593ec62bdad8621df910931349d964a6dbaa8c Mon Sep 17 00:00:00 2001
From: Ian Jackson
Date: Wed, 21 Oct 2015 16:18:30 +0100
Subject: [PATCH XSA-153 v3] libxl: adjust PoD target by memory fudge, too
PoD guests need to balloon at least as far as required by PoD, or risk
crashing. Currently they don't necessarily know what the right value
is, because our memory accounting is (at the very least) confusing.
Apply the memory limit fudge factor to the in-hypervisor PoD memory
target, too. This will increase the size of the guest's PoD cache by
the fudge factor LIBXL_MAXMEM_CONSTANT (currently 1Mby). This ensures
that even with a slightly-off balloon driver, the guest will be
stable even under memory pressure.
There are two call sites of xc_domain_set_pod_target that need fixing:
The one in libxl_set_memory_target is straightforward.
The one in xc_hvm_build_x86.c:setup_guest is more awkward. Simply
setting the PoD target differently does not work because the various
amounts of memory during domain construction no longer match up.
Instead, we adjust the guest memory target in xenstore (but only for
PoD guests).
This introduces a 1Mby discrepancy between the balloon target of a PoD
guest at boot, and the target set by an apparently-equivalent `xl
mem-set' (or similar) later. This approach is low-risk for a security
fix but we need to fix this up properly in xen.git#staging and
probably also in stable trees.
This is XSA-153.
Signed-off-by: Ian Jackson
---
tools/libxl/libxl.c | 2 +-
tools/libxl/libxl_dom.c | 9 ++++++++-
2 files changed, 9 insertions(+), 2 deletions(-)
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -4143,7 +4143,7 @@ retry_transaction:
new_target_memkb -= videoram;
rc = xc_domain_set_pod_target(ctx->xch, domid,
- new_target_memkb / 4, NULL, NULL, NULL);
+ (new_target_memkb + LIBXL_MAXMEM_CONSTANT) / 4, NULL, NULL, NULL);
if (rc != 0) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
"xc_domain_set_pod_target domid=%d, memkb=%d "
Index: xen-4.4.3-testing/tools/libxl/libxl_dom.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl_dom.c
+++ xen-4.4.3-testing/tools/libxl/libxl_dom.c
@@ -270,6 +270,7 @@ int libxl__build_post(libxl__gc *gc, uin
xs_transaction_t t;
char **ents, **hvm_ents;
int i, rc;
+ int64_t mem_target_fudge;
rc = libxl_domain_sched_params_set(CTX, domid, &info->sched_params);
if (rc)
@@ -286,11 +287,17 @@ int libxl__build_post(libxl__gc *gc, uin
if (info->cpuid != NULL)
libxl_cpuid_set(ctx, domid, info->cpuid);
+ mem_target_fudge =
+ (info->type == LIBXL_DOMAIN_TYPE_HVM &&
+ info->max_memkb > info->target_memkb)
+ ? LIBXL_MAXMEM_CONSTANT : 0;
+
ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
ents[0] = "memory/static-max";
ents[1] = GCSPRINTF("%"PRId64, info->max_memkb);
ents[2] = "memory/target";
- ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb);
+ ents[3] = GCSPRINTF("%"PRId64, info->target_memkb - info->video_memkb
+ - mem_target_fudge);
ents[4] = "memory/videoram";
ents[5] = GCSPRINTF("%"PRId64, info->video_memkb);
ents[6] = "domid";
++++++ xsa155-qemut-qdisk-double-access.patch ++++++
References: bsc#957988
From 27942b0cb2327e93deb12326bbe7b36c81f9fa7b Mon Sep 17 00:00:00 2001
From: Stefano Stabellini
Date: Fri, 20 Nov 2015 10:56:00 -0500
Subject: [PATCH] blkif: Avoid double access to src->nr_segments
src is stored in shared memory and src->nr_segments is dereferenced
twice at the end of the function. If a compiler decides to compile this
into two separate memory accesses then the size limitation could be
bypassed.
Fix it by removing the double access to src->nr_segments.
This is part of XSA-155.
Signed-off-by: Stefano Stabellini
Signed-off-by: Konrad Rzeszutek Wilk
---
hw/xen_blkif.h | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blkif.h
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blkif.h
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blkif.h
@@ -79,8 +79,10 @@ static inline void blkif_get_x86_32_req(
dst->handle = src->handle;
dst->id = src->id;
dst->sector_number = src->sector_number;
- if (n > src->nr_segments)
- n = src->nr_segments;
+ /* prevent the compiler from optimizing the code and using src->nr_segments instead */
+ xen_mb();
+ if (n > dst->nr_segments)
+ n = dst->nr_segments;
for (i = 0; i < n; i++)
dst->seg[i] = src->seg[i];
}
@@ -94,8 +96,10 @@ static inline void blkif_get_x86_64_req(
dst->handle = src->handle;
dst->id = src->id;
dst->sector_number = src->sector_number;
- if (n > src->nr_segments)
- n = src->nr_segments;
+ /* prevent the compiler from optimizing the code and using src->nr_segments instead */
+ xen_mb();
+ if (n > dst->nr_segments)
+ n = dst->nr_segments;
for (i = 0; i < n; i++)
dst->seg[i] = src->seg[i];
}
++++++ xsa155-qemut-xenfb.patch ++++++
References: bsc#957988
From 0ffd4547665d2fec648ab2c9ff856c5d9db9b07c Mon Sep 17 00:00:00 2001
From: Stefano Stabellini
Date: Fri, 20 Nov 2015 10:37:08 -0500
Subject: [PATCH 2/2] xenfb: avoid reading twice the same fields from the
shared page
Reading twice the same field could give the guest an attack of
opportunity. In the case of event->type, gcc could compile the switch
statement into a jump table, effectively ending up reading the type
field multiple times.
This is part of XSA-155.
Signed-off-by: Stefano Stabellini
---
hw/xenfb.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/hw/xenfb.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xenfb.c
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/hw/xenfb.c
@@ -827,18 +827,20 @@ static void xenfb_invalidate(void *opaqu
static void xenfb_handle_events(struct XenFB *xenfb)
{
- uint32_t prod, cons;
+ uint32_t prod, cons, out_cons;
struct xenfb_page *page = xenfb->c.page;
prod = page->out_prod;
- if (prod == page->out_cons)
+ out_cons = page->out_cons;
+ if (prod == out_cons)
return;
xen_rmb(); /* ensure we see ring contents up to prod */
- for (cons = page->out_cons; cons != prod; cons++) {
+ for (cons = out_cons; cons != prod; cons++) {
union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
+ uint8_t type = event->type;
int x, y, w, h;
- switch (event->type) {
+ switch (type) {
case XENFB_TYPE_UPDATE:
if (xenfb->up_count == UP_QUEUE)
xenfb->up_fullscreen = 1;
++++++ xsa155-qemuu-qdisk-double-access.patch ++++++
References: bsc#957988
xen/blkif: Avoid double access to src->nr_segments
src is stored in shared memory and src->nr_segments is dereferenced
twice at the end of the function. If a compiler decides to compile this
into two separate memory accesses then the size limitation could be
bypassed.
Fix it by removing the double access to src->nr_segments.
This is part of XSA-155.
Signed-off-by: Stefano Stabellini
Index: xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/block/xen_blkif.h
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-dir-remote/hw/block/xen_blkif.h
+++ xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/block/xen_blkif.h
@@ -79,8 +79,10 @@ static inline void blkif_get_x86_32_req(
dst->handle = src->handle;
dst->id = src->id;
dst->sector_number = src->sector_number;
- if (n > src->nr_segments)
- n = src->nr_segments;
+ /* prevent the compiler from optimizing the code and using src->nr_segments instead */
+ barrier();
+ if (n > dst->nr_segments)
+ n = dst->nr_segments;
for (i = 0; i < n; i++)
dst->seg[i] = src->seg[i];
}
@@ -94,8 +96,10 @@ static inline void blkif_get_x86_64_req(
dst->handle = src->handle;
dst->id = src->id;
dst->sector_number = src->sector_number;
- if (n > src->nr_segments)
- n = src->nr_segments;
+ /* prevent the compiler from optimizing the code and using src->nr_segments instead */
+ barrier();
+ if (n > dst->nr_segments)
+ n = dst->nr_segments;
for (i = 0; i < n; i++)
dst->seg[i] = src->seg[i];
}
++++++ xsa155-qemuu-xenfb.patch ++++++
References: bsc#957988
xenfb: avoid reading twice the same fields from the shared page
Reading twice the same field could give the guest an attack of
opportunity. In the case of event->type, gcc could compile the switch
statement into a jump table, effectively ending up reading the type
field multiple times.
This is part of XSA-155.
Signed-off-by: Stefano Stabellini
Index: xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/display/xenfb.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-dir-remote/hw/display/xenfb.c
+++ xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/display/xenfb.c
@@ -775,18 +775,20 @@ static void xenfb_invalidate(void *opaqu
static void xenfb_handle_events(struct XenFB *xenfb)
{
- uint32_t prod, cons;
+ uint32_t prod, cons, out_cons;
struct xenfb_page *page = xenfb->c.page;
prod = page->out_prod;
- if (prod == page->out_cons)
+ out_cons = page->out_cons;
+ if (prod == out_cons)
return;
xen_rmb(); /* ensure we see ring contents up to prod */
- for (cons = page->out_cons; cons != prod; cons++) {
+ for (cons = out_cons; cons != prod; cons++) {
union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons);
+ uint8_t type = event->type;
int x, y, w, h;
- switch (event->type) {
+ switch (type) {
case XENFB_TYPE_UPDATE:
if (xenfb->up_count == UP_QUEUE)
xenfb->up_fullscreen = 1;
++++++ xsa155-xen-0001-xen-Add-RING_COPY_REQUEST.patch ++++++
References: bsc#957988
From 12b11658a9d6a654a1e7acbf2f2d56ce9a396c86 Mon Sep 17 00:00:00 2001
From: David Vrabel
Date: Fri, 20 Nov 2015 11:59:05 -0500
Subject: [PATCH 1/3] xen: Add RING_COPY_REQUEST()
Using RING_GET_REQUEST() on a shared ring is easy to use incorrectly
(i.e., by not considering that the other end may alter the data in the
shared ring while it is being inspected). Safe usage of a request
generally requires taking a local copy.
Provide a RING_COPY_REQUEST() macro to use instead of
RING_GET_REQUEST() and an open-coded memcpy(). This takes care of
ensuring that the copy is done correctly regardless of any possible
compiler optimizations.
Use a volatile source to prevent the compiler from reordering or
omitting the copy.
This is part of XSA155.
Signed-off-by: David Vrabel
Signed-off-by: Konrad Rzeszutek Wilk
---
v2: Add comment about GCC bug.
---
xen/include/public/io/ring.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
Index: xen-4.4.3-testing/xen/include/public/io/ring.h
===================================================================
--- xen-4.4.3-testing.orig/xen/include/public/io/ring.h
+++ xen-4.4.3-testing/xen/include/public/io/ring.h
@@ -212,6 +212,20 @@ typedef struct __name##_back_ring __name
#define RING_GET_REQUEST(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
+/*
+ * Get a local copy of a request.
+ *
+ * Use this in preference to RING_GET_REQUEST() so all processing is
+ * done on a local copy that cannot be modified by the other end.
+ *
+ * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
+ * to be ineffective where _req is a struct which consists of only bitfields.
+ */
+#define RING_COPY_REQUEST(_r, _idx, _req) do { \
+ /* Use volatile to force the copy into _req. */ \
+ *(_req) = *(volatile typeof(_req))RING_GET_REQUEST(_r, _idx); \
+} while (0)
+
#define RING_GET_RESPONSE(_r, _idx) \
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
++++++ xsa155-xen-0002-blktap2-Use-RING_COPY_REQUEST.patch ++++++
References: bsc#957988
From 851ffb4eea917e2708c912291dea4d133026c0ac Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk
Date: Fri, 20 Nov 2015 12:16:02 -0500
Subject: [PATCH 2/3] blktap2: Use RING_COPY_REQUEST
Instead of RING_GET_REQUEST. Using a local copy of the
ring (and also with proper memory barriers) will mean
we can do not have to worry about the compiler optimizing
the code and doing a double-fetch in the shared memory space.
This is part of XSA155.
Signed-off-by: Konrad Rzeszutek Wilk
---
v2: Fix compile issues with tapdisk-vbd
---
tools/blktap2/drivers/block-log.c | 3 ++-
tools/blktap2/drivers/tapdisk-vbd.c | 8 ++++----
2 files changed, 6 insertions(+), 5 deletions(-)
Index: xen-4.4.3-testing/tools/blktap2/drivers/block-log.c
===================================================================
--- xen-4.4.3-testing.orig/tools/blktap2/drivers/block-log.c
+++ xen-4.4.3-testing/tools/blktap2/drivers/block-log.c
@@ -494,11 +494,12 @@ static int ctl_kick(struct tdlog_state*
reqstart = s->bring.req_cons;
reqend = s->sring->req_prod;
+ xen_mb();
BDPRINTF("ctl: ring kicked (start = %u, end = %u)", reqstart, reqend);
while (reqstart != reqend) {
/* XXX actually submit these! */
- memcpy(&req, RING_GET_REQUEST(&s->bring, reqstart), sizeof(req));
+ RING_COPY_REQUEST(&s->bring, reqstart, &req);
BDPRINTF("ctl: read request %"PRIu64":%u", req.sector, req.count);
s->bring.req_cons = ++reqstart;
Index: xen-4.4.3-testing/tools/blktap2/drivers/tapdisk-vbd.c
===================================================================
--- xen-4.4.3-testing.orig/tools/blktap2/drivers/tapdisk-vbd.c
+++ xen-4.4.3-testing/tools/blktap2/drivers/tapdisk-vbd.c
@@ -1555,7 +1555,7 @@ tapdisk_vbd_pull_ring_requests(td_vbd_t
int idx;
RING_IDX rp, rc;
td_ring_t *ring;
- blkif_request_t *req;
+ blkif_request_t req;
td_vbd_request_t *vreq;
ring = &vbd->ring;
@@ -1566,16 +1566,16 @@ tapdisk_vbd_pull_ring_requests(td_vbd_t
xen_rmb();
for (rc = ring->fe_ring.req_cons; rc != rp; rc++) {
- req = RING_GET_REQUEST(&ring->fe_ring, rc);
+ RING_COPY_REQUEST(&ring->fe_ring, rc, &req);
++ring->fe_ring.req_cons;
- idx = req->id;
+ idx = req.id;
vreq = &vbd->request_list[idx];
ASSERT(list_empty(&vreq->next));
ASSERT(vreq->secs_pending == 0);
- memcpy(&vreq->req, req, sizeof(blkif_request_t));
+ memcpy(&vreq->req, &req, sizeof(blkif_request_t));
vbd->received++;
vreq->vbd = vbd;
++++++ xsa155-xen-0003-libvchan-Read-prod-cons-only-once.patch ++++++
References: bsc#957988
From ef86ad0b60fe179b1a6fa390e05c339fb44b9cc9 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk
Date: Fri, 20 Nov 2015 12:22:14 -0500
Subject: [PATCH] libvchan: Read prod/cons only once.
We must ensure that the prod/cons are only read once and that
the compiler won't try to optimize the reads. That is split
the read of these in multiple instructions influencing later
branch code. As such insert barriers when fetching the cons
and prod index.
This is part of XSA155.
Signed-off-by: Konrad Rzeszutek Wilk
---
tools/libvchan/io.c | 2 ++
1 file changed, 2 insertions(+)
Index: xen-4.4.3-testing/tools/libvchan/io.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libvchan/io.c
+++ xen-4.4.3-testing/tools/libvchan/io.c
@@ -118,6 +118,7 @@ static inline int send_notify(struct lib
static inline int raw_get_data_ready(struct libxenvchan *ctrl)
{
uint32_t ready = rd_prod(ctrl) - rd_cons(ctrl);
+ xen_mb(); /* Ensure 'ready' is read only once. */
if (ready >= rd_ring_size(ctrl))
/* We have no way to return errors. Locking up the ring is
* better than the alternatives. */
@@ -159,6 +160,7 @@ int libxenvchan_data_ready(struct libxen
static inline int raw_get_buffer_space(struct libxenvchan *ctrl)
{
uint32_t ready = wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl));
+ xen_mb(); /* Ensure 'ready' is read only once. */
if (ready > wr_ring_size(ctrl))
/* We have no way to return errors. Locking up the ring is
* better than the alternatives. */
++++++ xsa162-qemut.patch ++++++
net: pcnet: add check to validate receive data size(CVE-2015-7504)
In loopback mode, pcnet_receive routine appends CRC code to the
receive buffer. If the data size given is same as the buffer size,
the appended CRC code overwrites 4 bytes after s->buffer. Added a
check to avoid that.
---
hw/net/pcnet.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
Index: xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c
+++ xen-4.4.3-testing/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c
@@ -1153,7 +1153,7 @@ static void pcnet_receive(void *opaque,
uint32_t fcs = ~0;
uint8_t *p = src;
- while (p != &src[size-4])
+ while (p != &src[size])
CRC(fcs, *p++);
crc_err = (*(uint32_t *)p != htonl(fcs));
}
@@ -1284,12 +1284,13 @@ static void pcnet_transmit(PCNetState *s
bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
/* if multi-tmd packet outsizes s->buffer then skip it silently.
- Note: this is not what real hw does */
- if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
- s->xmit_pos = -1;
- goto txdone;
+ * Note: this is not what real hw does.
+ * Last four bytes of s->buffer are used to store CRC FCS code.
+ */
+ if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) {
+ s->xmit_pos = -1;
+ goto txdone;
}
-
s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
s->xmit_pos += bcnt;
++++++ xsa162-qemuu.patch ++++++
net: pcnet: add check to validate receive data size(CVE-2015-7504)
In loopback mode, pcnet_receive routine appends CRC code to the
receive buffer. If the data size given is same as the buffer size,
the appended CRC code overwrites 4 bytes after s->buffer. Added a
check to avoid that.
---
hw/net/pcnet.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
Index: xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/net/pcnet.c
===================================================================
--- xen-4.4.3-testing.orig/tools/qemu-xen-dir-remote/hw/net/pcnet.c
+++ xen-4.4.3-testing/tools/qemu-xen-dir-remote/hw/net/pcnet.c
@@ -1107,7 +1107,7 @@ ssize_t pcnet_receive(NetClientState *nc
uint32_t fcs = ~0;
uint8_t *p = src;
- while (p != &src[size-4])
+ while (p != &src[size])
CRC(fcs, *p++);
crc_err = (*(uint32_t *)p != htonl(fcs));
}
@@ -1256,8 +1256,10 @@ static void pcnet_transmit(PCNetState *s
bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
/* if multi-tmd packet outsizes s->buffer then skip it silently.
- Note: this is not what real hw does */
- if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
+ * Note: this is not what real hw does.
+ * Last four bytes of s->buffer are used to store CRC FCS code.
+ */
+ if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) {
s->xmit_pos = -1;
goto txdone;
}
++++++ xsa164.patch ++++++
References: bsc#958007 XSA-164
MSI-X: avoid array overrun upon MSI-X table writes
pt_msix_init() allocates msix->msix_entry[] to just cover
msix->total_entries entries. While pci_msix_readl() resorts to reading
physical memory for out of bounds reads, pci_msix_writel() so far
simply accessed/corrupted unrelated memory.
pt_iomem_map()'s call to cpu_register_physical_memory() registers a
page granular region, which is necessary as the Pending Bit Array may
share space with the MSI-X table (but nothing else is allowed to). This
also explains why pci_msix_readl() actually honors out of bounds reads,
but pci_msi_writel() doesn't need to.
This is XSA-164.
Signed-off-by: Jan Beulich
--- a/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.c
+++ b/tools/qemu-xen-traditional-dir-remote/hw/pt-msi.c
@@ -440,6 +440,13 @@ static void pci_msix_writel(void *opaque
return;
}
+ if ( addr - msix->mmio_base_addr >= msix->total_entries * 16 )
+ {
+ PT_LOG("Error: Out of bounds write to MSI-X table,"
+ " addr %016"PRIx64"\n", addr);
+ return;
+ }
+
entry_nr = (addr - msix->mmio_base_addr) / 16;
entry = &msix->msix_entry[entry_nr];
offset = ((addr - msix->mmio_base_addr) % 16) / 4;
++++++ xsa165.patch ++++++
References: bsc#958009 XSA-165
x86: don't leak ST(n)/XMMn values to domains first using them
FNINIT doesn't alter these registers, and hence using it is
insufficient to initialize a guest's initial state.
This is XSA-165.
Signed-off-by: Jan Beulich
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -751,6 +751,17 @@ int arch_set_info_guest(
if ( v->arch.xsave_area )
v->arch.xsave_area->xsave_hdr.xstate_bv = XSTATE_FP_SSE;
}
+ else if ( v->arch.xsave_area )
+ memset(&v->arch.xsave_area->xsave_hdr, 0,
+ sizeof(v->arch.xsave_area->xsave_hdr));
+ else
+ {
+ typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt;
+
+ memset(fpu_sse, 0, sizeof(*fpu_sse));
+ fpu_sse->fcw = FCW_DEFAULT;
+ fpu_sse->mxcsr = MXCSR_DEFAULT;
+ }
if ( !compat )
{
--- a/xen/arch/x86/i387.c
+++ b/xen/arch/x86/i387.c
@@ -17,19 +17,6 @@
#include
#include
-static void fpu_init(void)
-{
- unsigned long val;
-
- asm volatile ( "fninit" );
- if ( cpu_has_xmm )
- {
- /* load default value into MXCSR control/status register */
- val = MXCSR_DEFAULT;
- asm volatile ( "ldmxcsr %0" : : "m" (val) );
- }
-}
-
/*******************************/
/* FPU Restore Functions */
/*******************************/
@@ -248,15 +235,8 @@ void vcpu_restore_fpu_lazy(struct vcpu *
if ( cpu_has_xsave )
fpu_xrstor(v, XSTATE_LAZY);
- else if ( v->fpu_initialised )
- {
- if ( cpu_has_fxsr )
- fpu_fxrstor(v);
- else
- fpu_frstor(v);
- }
else
- fpu_init();
+ fpu_fxrstor(v);
v->fpu_initialised = 1;
v->fpu_dirtied = 1;
@@ -317,7 +297,14 @@ int vcpu_init_fpu(struct vcpu *v)
else
{
v->arch.fpu_ctxt = _xzalloc(sizeof(v->arch.xsave_area->fpu_sse), 16);
- if ( !v->arch.fpu_ctxt )
+ if ( v->arch.fpu_ctxt )
+ {
+ typeof(v->arch.xsave_area->fpu_sse) *fpu_sse = v->arch.fpu_ctxt;
+
+ fpu_sse->fcw = FCW_DEFAULT;
+ fpu_sse->mxcsr = MXCSR_DEFAULT;
+ }
+ else
{
rc = -ENOMEM;
goto done;
++++++ xsa166.patch ++++++
References: bsc#958523 XSA-166
x86/HVM: avoid reading ioreq state more than once
Otherwise, especially when the compiler chooses to translate the
switch() to a jump table, unpredictable behavior (and in the jump table
case arbitrary code execution) can result.
This is XSA-166.
Signed-off-by: Jan Beulich
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -348,6 +348,7 @@ void hvm_migrate_pirqs(struct vcpu *v)
void hvm_do_resume(struct vcpu *v)
{
ioreq_t *p;
+ unsigned int state;
check_wakeup_from_wait();
@@ -358,9 +359,10 @@ void hvm_do_resume(struct vcpu *v)
if ( !(p = get_ioreq(v)) )
goto check_inject_trap;
- while ( p->state != STATE_IOREQ_NONE )
+ while ( (state = p->state) != STATE_IOREQ_NONE )
{
- switch ( p->state )
+ rmb();
+ switch ( state )
{
case STATE_IORESP_READY: /* IORESP_READY -> NONE */
hvm_io_assist(p);
@@ -368,11 +370,10 @@ void hvm_do_resume(struct vcpu *v)
case STATE_IOREQ_READY: /* IOREQ_{READY,INPROCESS} -> IORESP_READY */
case STATE_IOREQ_INPROCESS:
wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port,
- (p->state != STATE_IOREQ_READY) &&
- (p->state != STATE_IOREQ_INPROCESS));
+ p->state != state);
break;
default:
- gdprintk(XENLOG_ERR, "Weird HVM iorequest state %d.\n", p->state);
+ gdprintk(XENLOG_ERR, "Weird HVM iorequest state %u\n", state);
domain_crash(v->domain);
return; /* bail */
}