File xend-traditional-qemu.patch of Package xen.openSUSE_13.1_Update

From 9ca313aa0824f2d350a7a6c9b1ef6c47e0408f1d Mon Sep 17 00:00:00 2001
From: aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
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 <aliguori@us.ibm.com>



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.3.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c
+++ xen-4.3.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 */
@@ -1342,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);
@@ -1445,7 +1437,28 @@ 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 == 0xffea && keyboard_layout && !strcmp(keyboard_layout,"es") )
+        sym = 0xffe9;
+
+    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 +1547,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 +1584,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:
@@ -1734,6 +1759,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)
@@ -1774,6 +1818,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 +2507,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 */
@@ -2564,6 +2627,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.3.0-testing/tools/hotplug/Linux/init.d/sysconfig.xendomains
===================================================================
--- xen-4.3.0-testing.orig/tools/hotplug/Linux/init.d/sysconfig.xendomains
+++ xen-4.3.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.3.0-testing/tools/examples/xend-config.sxp
===================================================================
--- xen-4.3.0-testing.orig/tools/examples/xend-config.sxp
+++ xen-4.3.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
@@ -194,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.
@@ -203,7 +229,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.
@@ -224,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
@@ -295,6 +324,70 @@
 # 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] -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.
+# 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)
+
+# 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.3.0-testing/tools/python/xen/xm/create.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.3.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
@@ -73,7 +73,7 @@ gopts.opt('quiet', short='q',
           use="Quiet.")
 
 gopts.opt('path', val='PATH',
-          fn=set_value, default='.:' + auxbin.xen_configdir(),
+          fn=set_value, default='.:' + auxbin.xen_configdir() + "/vm",
           use="Search path for configuration scripts. "
           "The value of PATH is a colon-separated directory list.")
 
@@ -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.")
@@ -473,6 +477,26 @@ 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('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.")
@@ -517,6 +541,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")
@@ -1032,7 +1071,11 @@ 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',
              'gfx_passthru', 'guest_os_type',
              'hap', 'hpet',
@@ -1047,7 +1090,8 @@ 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' ]
 
@@ -1056,6 +1100,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):
@@ -1274,9 +1322,8 @@ def preprocess_access_control(vals):
 
 def preprocess_ip(vals):
     if vals.ip or vals.dhcp != 'off':
-        dummy_nfs_server = '127.0.255.255'
         ip = (vals.ip
-          + ':' + (vals.nfs_server or dummy_nfs_server)
+          + ':' + (vals.nfs_server or '')
           + ':' + vals.gateway
           + ':' + vals.netmask
           + ':' + vals.hostname
@@ -1465,7 +1512,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 +1520,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.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
@@ -79,7 +79,7 @@ in the config file.  See L<xmdomain.cfg>
 format, and possible options used in either the configfile or for I<vars>.
 
 I<configfile> can either be an absolute path to a file, or a relative
-path to a file located in /etc/xen.
+path to a file located in /etc/xen/vm.
 
 Create will return B<as soon> as the domain is started.  This B<does
 not> mean the guest OS in the domain has actually booted, or is
@@ -160,7 +160,7 @@ B<EXAMPLES>
 
   xm create Fedora4
 
-This creates a domain with the file /etc/xen/Fedora4, and returns as
+This creates a domain with the file /etc/xen/vm/Fedora4, and returns as
 soon as it is run.
 
 =item I<without config file>
@@ -299,7 +299,8 @@ scheduling by the Xen hypervisor.
 
 =item B<s - shutdown>
 
-FIXME: Why would you ever see this state?
+The guest has requested to be shutdown, rebooted or suspended, and the
+domain is in the process of being destroyed in response.
 
 =item B<c - crashed>
 
@@ -312,8 +313,6 @@ restart on crash.  See L<xmdomain.cfg> f
 The domain is in process of dying, but hasn't completely shutdown or
 crashed.
 
-FIXME: Is this right?
-
 =back
 
 B<NOTES>
@@ -737,8 +736,6 @@ Xen ships with a number of domain schedu
 time with the B<sched=> parameter on the Xen command line.  By
 default B<credit> is used for scheduling.
 
-FIXME: we really need a scheduler expert to write up this section.
-
 =over 4
 
 =item B<sched-credit> [ B<-d> I<domain-id> [ B<-w>[B<=>I<WEIGHT>] | B<-c>[B<=>I<CAP>] ] ]
@@ -801,8 +798,6 @@ The normal EDF scheduling usage in nanos
 
 The normal EDF scheduling usage in nanoseconds
 
-FIXME: these are lame, should explain more.
-
 =item I<latency-hint>
 
 Scaled period if domain is doing heavy I/O.
@@ -952,9 +947,6 @@ the default setting in xend-config.sxp f
 
 Passes the specified IP Address to the adapter on creation.  
 
-FIXME: this currently appears to be B<broken>.  I'm not sure under what
-circumstances this should actually work.
-
 =item B<mac=>I<macaddr>
 
 The MAC address that the domain will see on its Ethernet device.  If
@@ -980,9 +972,6 @@ Removes the network device from the doma
 I<devid> is the virtual interface device number within the domain
 (i.e. the 3 in vif22.3).
 
-FIXME: this is currently B<broken>.  Network devices aren't completely
-removed from domain 0.
-
 =item B<network-list> [B<-l>|B<--long>]> I<domain-id>
 
 List virtual network interfaces for a domain.  The returned output is
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
@@ -4,9 +4,9 @@ xmdomain.cfg - xm domain config file for
 
 =head1 SYNOPSIS
 
- /etc/xen/myxendomain
- /etc/xen/myxendomain2
- /etc/xen/auto/myxenautostarted
+ /etc/xen/auto/
+ /etc/xen/examples/
+ /etc/xen/vm/
 
 =head1 DESCRIPTION
 
@@ -14,14 +14,14 @@ The B<xm>(1) program uses python executa
 domains to create from scratch.  Each of these config files needs to
 contain a number of required options, and may specify many more.
 
-Domain configuration files live in /etc/xen by default, if you store
+Domain configuration files live in /etc/xen/vm by default.  If you store
 config files anywhere else the full path to the config file must be
 specified in the I<xm create> command.
 
 /etc/xen/auto is a special case.  Domain config files in that
 directory will be started automatically at system boot if the
 xendomain init script is enabled.  The contents of /etc/xen/auto
-should be symlinks to files in /etc/xen to allow I<xm create> to be
+should be symlinks to files in /etc/xen/vm to allow I<xm create> to be
 used without full paths.
 
 Options are specified by I<name = value> statements in the
@@ -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<acpi_firmware>
+
+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<smbios_firmware>
+
+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
@@ -333,16 +352,10 @@ at hda1, which is the root filesystem.
 
 =item I<NFS Root>
 
-FIXME: write me
-
 =item I<LVM Root>
 
-FIXME: write me
-
 =item I<Two Networks>
 
-FIXME: write me
-
 =back
 
 =head1 SEE ALSO
Index: xen-4.3.0-testing/tools/python/xen/xend/server/DevController.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/server/DevController.py
+++ xen-4.3.0-testing/tools/python/xen/xend/server/DevController.py
@@ -149,13 +149,16 @@ 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))
 
         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." %
@@ -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']
 
@@ -592,6 +610,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.3.0-testing/tools/python/xen/xend/XendBootloader.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendBootloader.py
+++ xen-4.3.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.3.0-testing/tools/python/xen/xend/XendDomainInfo.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.3.0-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -74,7 +74,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()
@@ -303,7 +303,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):
@@ -317,6 +318,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.
 
@@ -470,6 +485,8 @@ 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)
                 
@@ -496,6 +513,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:
@@ -712,6 +730,8 @@ class XendDomainInfo:
         the device.
         """
 
+        if self.domid is None:
+            return
         self.iommu_check_pod_mode()
 
         # Test whether the devices can be assigned
@@ -851,6 +871,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':
@@ -864,6 +887,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')
@@ -908,6 +932,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():
@@ -984,6 +1012,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():
@@ -1203,6 +1234,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)
@@ -1295,8 +1329,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
@@ -1459,6 +1500,52 @@ class XendDomainInfo:
         pci_conf = self.info['devices'][dev_uuid][1]
         return map(pci_dict_to_bdf_str, pci_conf['devs'])
 
+    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 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)
+
+    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.
@@ -1923,6 +2010,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']
@@ -2247,6 +2336,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()
@@ -2283,7 +2374,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)
@@ -2333,6 +2424,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)
@@ -2734,7 +2829,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'))
@@ -2884,7 +2982,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)
@@ -2919,6 +3017,9 @@ class XendDomainInfo:
 
             self._createDevices()
 
+            if self.image:
+                self.image.createXenPaging()
+
             self.image.cleanupTmpImages()
 
             self.info['start_time'] = time.time()
@@ -2943,6 +3044,8 @@ class XendDomainInfo:
         self.refresh_shutdown_lock.acquire()
         try:
             self.unwatchShutdown()
+            if self.image:
+                self.image.destroyXenPaging()
             self._releaseDevices()
             bootloader_tidy(self)
 
@@ -2956,6 +3059,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()
 
@@ -3011,7 +3119,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")
 
@@ -3022,6 +3130,8 @@ 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()
         self.refreshShutdown()
@@ -3099,9 +3209,15 @@ 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()
 
+        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 \
@@ -3157,6 +3273,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()
@@ -3172,6 +3290,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)
@@ -3271,32 +3391,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': 'RO',
-                    'device': BOOTLOADER_LOOPBACK_DEVICE,
-                    }
-
-                from xen.xend import XendDomain
-                dom0 = XendDomain.instance().privilegedDomain()
-                mounted_vbd_uuid = dom0.create_vbd(vbd, disk);
-                dom0._waitForDeviceUUID(mounted_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))
-                    _, vbd_info = dom0.info['devices'][mounted_vbd_uuid]
-                    dom0.destroyDevice(dom0.getBlockDeviceClass(vbd_info['devid']), 
-                                       BOOTLOADER_LOOPBACK_DEVICE, force = True)
-
+                             (fn, loopback_device))
+                    if devtype in ['tap', 'tap2']:
+                        dom0.destroyDevice('tap', loopback_device, rm_cfg = True)
+                    else:
+                        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)
@@ -3908,6 +4034,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):
@@ -4415,6 +4549,91 @@ 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):
+        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:
+            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())
+
+        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)
+        except:
+            log.exception("%s could not be created." % path)
+            raise XendError("%s could not be created." % 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))
+
+    # 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())
+
+        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:
+            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.3.0-testing/tools/python/xen/xm/main.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xm/main.py
+++ xen-4.3.0-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
@@ -114,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.'),
@@ -121,7 +124,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.'),
@@ -280,6 +283,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 = {
@@ -341,6 +347,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'),
@@ -404,6 +411,7 @@ common_commands = [
     "usb-del",
     "domstate",
     "vcpu-set",
+    "change-vnc-passwd",
     ]
 
 domain_commands = [
@@ -441,6 +449,7 @@ domain_commands = [
     "vcpu-list",
     "vcpu-pin",
     "vcpu-set",
+    "change-vnc-passwd",
     ]
 
 host_commands = [
@@ -862,18 +871,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")
@@ -887,9 +899,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)
@@ -1580,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])
@@ -2199,6 +2222,10 @@ def xm_debug_keys(args):
 def xm_top(args):
     arg_check(args, "top", 0)
 
+    # A hack to get a clear error message if ran as non-root
+    if os.geteuid() != 0:
+        raise IOError()
+
     os.system('xentop')
 
 def xm_dmesg(args):
@@ -2586,10 +2613,22 @@ def xm_usb_list(args):
         ni = parse_dev_info(x[1])
         ni['idx'] = int(x[0])
         usbver = sxp.child_value(x[1], 'usb-ver')
+
+        substr = re.search("^\d{1,}", usbver)
+        if substr:
+            usbver = substr.group()
+        else:
+            print "Unknown usb-ver"
+            continue
+
         if int(usbver) == 1:
             ni['usb-ver'] = 'USB1.1'
-        else:
+        elif int(usbver) == 2:
             ni['usb-ver'] = 'USB2.0'
+        else:
+            print "Unknown usb-ver"
+            continue
+
         print "%(idx)-3d %(backend-id)-3d %(state)-5d %(usb-ver)-7s %(be-path)-30s  " % ni
 
         ports = sxp.child(x[1], 'port')
@@ -3751,6 +3790,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,
@@ -3782,6 +3825,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,
@@ -3857,6 +3901,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.3.0-testing/tools/python/xen/xend/XendNode.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendNode.py
+++ xen-4.3.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.")
@@ -949,11 +961,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 +1000,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.3.0-testing/tools/python/xen/xend/balloon.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/balloon.py
+++ xen-4.3.0-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.3.0-testing/tools/python/xen/xend/server/SrvDomain.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/server/SrvDomain.py
+++ xen-4.3.0-testing/tools/python/xen/xend/server/SrvDomain.py
@@ -187,7 +187,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.3.0-testing/tools/python/xen/xend/osdep.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/osdep.py
+++ xen-4.3.0-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' }
@@ -141,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
Index: xen-4.3.0-testing/tools/hotplug/Linux/Makefile
===================================================================
--- xen-4.3.0-testing.orig/tools/hotplug/Linux/Makefile
+++ xen-4.3.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
@@ -23,6 +23,8 @@ 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 += domain-lock-sfex
 XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
 XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
 XEN_SCRIPT_DATA += block-common.sh
Index: xen-4.3.0-testing/tools/hotplug/Linux/vif-route-ifup
===================================================================
--- /dev/null
+++ xen-4.3.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
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/net.h
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/net.h
+++ xen-4.3.0-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.3.0-testing/tools/qemu-xen-traditional-dir-remote/net.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/net.c
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/net.c
@@ -1759,9 +1759,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.3.0-testing/tools/python/xen/xend/image.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.3.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
@@ -122,7 +122,13 @@ 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')))
         self.display = vmConfig['platform'].get('display')
         self.xauthority = vmConfig['platform'].get('xauthority')
         self.vncconsole = int(vmConfig['platform'].get('vncconsole', 0))
@@ -392,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
@@ -828,6 +915,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:
@@ -855,7 +943,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 +952,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']:
@@ -912,11 +1002,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:
@@ -941,6 +1033,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()
 
@@ -956,6 +1080,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,
@@ -964,7 +1090,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(),
@@ -1036,7 +1164,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):
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/i386-dm/qemu-ifup-Linux
+++ xen-4.3.0-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
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/monitor.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/monitor.c
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/monitor.c
@@ -26,6 +26,7 @@
 #include "hw/pcmcia.h"
 #include "hw/pc.h"
 #include "hw/pci.h"
+#include "hw/watchdog.h"
 #include "gdbstub.h"
 #include "net.h"
 #include "qemu-char.h"
@@ -531,6 +532,13 @@ static void do_gdbserver(const char *por
 }
 #endif
 
+static void do_watchdog_action(const char *action)
+{
+    if (select_watchdog_action(action) == -1) {
+        qemu_printf("Unknown watchdog action '%s'\n", action);
+    }
+}
+
 static void term_printc(int c)
 {
     term_printf("'");
@@ -1497,6 +1505,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 +1518,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 +1548,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 +1570,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 +1578,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,
@@ -1599,6 +1613,8 @@ static const term_cmd_t term_cmds[] = {
       "target", "request VM to change it's memory allocation (in MB)" },
     { "set_link", "ss", do_set_link,
       "name [up|down]", "change the link status of a network adapter" },
+    { "watchdog_action", "s", do_watchdog_action,
+      "[reset|shutdown|poweroff|pause|debug|none]", "change watchdog action" },
     { "cpu_set", "is", do_cpu_set_nr,
       "cpu [online|offline]", "change cpu state" },
     { NULL, NULL, },
@@ -1646,6 +1662,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 +1694,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, },
 };
 
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ne2000.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/ne2000.c
+++ xen-4.3.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.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pc.c
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pc.c
@@ -41,6 +41,7 @@
 #include "virtio-balloon.h"
 #include "virtio-console.h"
 #include "hpet_emul.h"
+#include "watchdog.h"
 
 #ifdef CONFIG_PASSTHROUGH
 #include "pass-through.h"
@@ -413,7 +414,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 +438,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
@@ -472,45 +475,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;
 
-    memset(rom, 0, sizeof(rom));
+    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));
 
-    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 */
 
@@ -540,13 +526,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)
@@ -563,8 +543,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)
 {
@@ -630,7 +609,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 */
@@ -719,7 +700,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
 }
 
@@ -930,14 +911,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]);
@@ -971,6 +944,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];
@@ -1075,6 +1051,8 @@ vga_bios_error:
         }
     }
 
+    watchdog_pc_init(pci_bus);
+
     for(i = 0; i < nb_nics; i++) {
         NICInfo *nd = &nd_table[i];
 
Index: xen-4.3.0-testing/tools/python/xen/xend/server/HalDaemon.py
===================================================================
--- /dev/null
+++ xen-4.3.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 <plc@novell.com>
+# 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.3.0-testing/tools/python/xen/xend/server/Hald.py
===================================================================
--- /dev/null
+++ xen-4.3.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 <plc@novell.com>
+# 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.3.0-testing/tools/python/xen/xend/server/SrvServer.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/server/SrvServer.py
+++ xen-4.3.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.3.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/xenstore.c
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/xenstore.c
@@ -18,12 +18,14 @@
 #include "exec-all.h"
 #include "sysemu.h"
 
+#include "console.h"
 #include "hw.h"
 #include "pci.h"
 #include "qemu-timer.h"
 #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;
@@ -133,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;
@@ -443,13 +446,13 @@ 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;
-    char *fpath = NULL, *bpath = NULL,
+    char *fpath = NULL, *bpath = NULL, *btype = NULL,
         *dev = NULL, *params = NULL, *drv = NULL;
-    int i, ret;
+    int i, j, ret, is_tap;
     unsigned int len, num, hd_index, pci_devid = 0;
     BlockDriverState *bs;
     BlockDriver *format;
@@ -486,6 +489,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;
@@ -500,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)
@@ -525,12 +537,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;
@@ -538,6 +545,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, ':'); 
@@ -562,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.
@@ -596,6 +643,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);
@@ -614,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);
@@ -640,6 +702,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) {
@@ -672,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
@@ -762,6 +838,7 @@ void xenstore_parse_domain_config(int hv
     free(mode);
     free(params);
     free(dev);
+    free(btype);
     free(bpath);
     free(buf);
     free(danger_buf);
@@ -872,6 +949,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,
@@ -930,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);
     }
@@ -1086,6 +1179,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;
@@ -1121,6 +1258,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' -"
Index: xen-4.3.0-testing/tools/python/xen/xend/XendAuthSessions.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendAuthSessions.py
+++ xen-4.3.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):
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/Makefile
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/Makefile
+++ xen-4.3.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
@@ -243,7 +250,7 @@ endif
 install: all $(if $(BUILD_DOCS),install-doc)
 	mkdir -p "$(DESTDIR)$(bindir)"
 ifneq ($(TOOLS),)
-	$(INSTALL) -m 755 -s $(TOOLS) "$(DESTDIR)$(bindir)"
+	$(INSTALL) -m 755 $(TOOLS) "$(DESTDIR)$(bindir)"
 endif
 ifneq ($(BLOBS),)
 	mkdir -p "$(DESTDIR)$(datadir)"
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/Makefile.target
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/Makefile.target
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/Makefile.target
@@ -580,6 +580,10 @@ OBJS += e1000.o
 # Serial mouse
 OBJS += msmouse.o
 
+# Generic watchdog support and some watchdog devices
+OBJS += watchdog.o
+OBJS += wdt_ib700.o wdt_i6300esb.o
+
 ifeq ($(TARGET_BASE_ARCH), i386)
 # Hardware support
 ifdef CONFIG_AUDIO
@@ -755,7 +759,7 @@ clean:
 
 install: all install-hook
 ifneq ($(PROGS),)
-	$(INSTALL) -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)"
+	$(INSTALL) -m 755 $(PROGS) "$(DESTDIR)$(bindir)"
 endif
 
 # Include automatically generated dependency files
Index: xen-4.3.0-testing/tools/python/xen/xend/XendCheckpoint.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendCheckpoint.py
+++ xen-4.3.0-testing/tools/python/xen/xend/XendCheckpoint.py
@@ -123,6 +123,11 @@ def save(fd, dominfo, network, live, dst
                str(int(live) | (int(hvm) << 2)) ]
         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":
@@ -172,7 +177,10 @@ def save(fd, dominfo, network, live, dst
             dominfo.destroy()
             dominfo.testDeviceComplete()
         try:
-            dominfo.setName(domain_name, False)
+            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
@@ -184,6 +192,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)
@@ -326,8 +337,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
@@ -351,6 +361,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.3.0-testing/tools/python/xen/xend/XendAPI.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendAPI.py
+++ xen-4.3.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.3.0-testing/tools/python/xen/xend/XendDomain.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendDomain.py
+++ xen-4.3.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:
@@ -1832,6 +1835,21 @@ class XendDomain:
             log.exception(ex)
             raise XendError(str(ex))
 
+    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.3.0-testing/tools/python/xen/xend/XendAPIConstants.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendAPIConstants.py
+++ xen-4.3.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'
 ]
Index: xen-4.3.0-testing/tools/python/xen/xend/XendConfig.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.3.0-testing/tools/python/xen/xend/XendConfig.py
@@ -147,6 +147,11 @@ 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,
     'display' : str,
     'fda': str,
@@ -159,6 +164,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
     'nographic': int,
     'nomigrate': int,
     'pae' : int,
+    'extid': int,
     'rtc_timeoffset': int,
     'parallel': str,
     'serial': str,
@@ -192,6 +198,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.
@@ -512,8 +520,20 @@ 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']:
+                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']:
@@ -1865,7 +1885,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
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_console.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_console.c
+++ xen-4.3.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)
Index: xen-4.3.0-testing/tools/python/xen/xm/xenapi_create.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xm/xenapi_create.py
+++ xen-4.3.0-testing/tools/python/xen/xm/xenapi_create.py
@@ -740,7 +740,7 @@ class sxp2xml:
 
         if get_child_by_name(config, "maxmem"):
             memory.attributes["static_max"] = \
-               str(int(get_child_by_name(config, "maxmem")*1024*1024))
+               str(int(get_child_by_name(config, "maxmem"))*1024*1024)
 
         vm.appendChild(memory)
 
@@ -1046,7 +1046,12 @@ class sxp2xml:
             'acpi',
             'apic',
             'boot',
+            'actmem',
+            'xenpaging_file',
+            'xenpaging_extra',
             'device_model',
+            'smbios_firmware',
+            'acpi_firmware',
             'loader',
             'fda',
             'fdb',
@@ -1074,7 +1079,9 @@ class sxp2xml:
             'xen_platform_pci',
             'tsc_mode'
             'description',
-            'nomigrate'
+            'nomigrate',
+            'watchdog',
+            'watchdog_action'
         ]
 
         platform_configs = []
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_machine_fv.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_machine_fv.c
+++ xen-4.3.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
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.c
+++ xen-4.3.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)
@@ -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);
@@ -218,11 +219,13 @@ 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 flags = readonly ? BDRV_O_RDONLY : BDRV_O_RDWR;
 	int i;
 
 	DPRINTF("Opening %s as blktap%d\n", path, devnumber);
@@ -230,7 +233,25 @@ 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
+         * 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;
 	}
@@ -240,6 +261,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
@@ -337,6 +364,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).
  *
@@ -355,6 +391,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;
 
@@ -387,7 +424,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;
 		}
@@ -408,7 +445,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) 
@@ -421,8 +458,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));
 
@@ -442,6 +485,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:
@@ -519,9 +566,10 @@ 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->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;
@@ -569,7 +617,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.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.h
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_blktap.h
+++ xen-4.3.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_*/
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/configure
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/configure
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/configure
@@ -1511,7 +1511,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.3.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-tool.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/qemu-tool.c
+++ xen-4.3.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.3.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/tapdisk-ioemu.c
@@ -12,34 +12,13 @@
 
 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;
+extern int connected_disks;
 
 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;
@@ -98,25 +77,29 @@ 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)
+        exit(0);
 
-    logfile = stderr;
-    
     bdrv_init();
-    qemu_aio_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.
      */
     while (1) {
-        qemu_aio_poll();
-
         max_fd = -1;
         FD_ZERO(&rfds);
         for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next)
@@ -146,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;
 }
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/block.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block.c
+++ xen-4.3.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);
@@ -595,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;
@@ -630,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;
@@ -933,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)
 {
@@ -1463,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) {
@@ -1488,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.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/usb-msd.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/usb-msd.c
+++ xen-4.3.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.3.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-img.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/qemu-img.c
+++ xen-4.3.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);
     }
 
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/block-qcow2.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block-qcow2.c
+++ xen-4.3.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:
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/xen_platform.c
+++ xen-4.3.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 <xc_private.h>
 
 #include <assert.h>
 #include <xenguest.h>
@@ -335,11 +337,71 @@ 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 SCSI hard disk...\n");
+        pci_unplug_scsi();
+        fprintf(logfile, "Disconnect netifs...\n");
+        pci_unplug_netifs();
+        fprintf(logfile, "Shutdown taps...\n");
+        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);
+        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);
+
 }
 
 static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ide.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/ide.c
+++ xen-4.3.0-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);
@@ -2365,7 +2368,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;
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vl.c
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/vl.c
@@ -30,6 +30,7 @@
 #include "hw/isa.h"
 #include "hw/baum.h"
 #include "hw/bt.h"
+#include "hw/watchdog.h"
 #include "net.h"
 #include "console.h"
 #include "sysemu.h"
@@ -200,7 +201,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;
@@ -2627,6 +2628,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 +2643,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 +2664,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 */
@@ -4175,6 +4178,10 @@ static void help(int exitcode)
            "-startdate      select initial date of the clock\n"
            "-icount [N|auto]\n"
            "                enable virtual instruction counter with 2^N clock ticks per instruction\n"
+           "-watchdog i6300esb|ib700\n"
+           "                enable virtual hardware watchdog [default=none]\n"
+           "-watchdog-action reset|shutdown|poweroff|pause|debug|none\n"
+           "                action when watchdog fires [default=reset]\n"
            "-echr chr       set terminal escape character instead of ctrl-a\n"
            "-virtioconsole c\n"
            "                set virtio console\n"
@@ -4322,6 +4329,8 @@ enum {
     QEMU_OPTION_localtime,
     QEMU_OPTION_startdate,
     QEMU_OPTION_icount,
+    QEMU_OPTION_watchdog,
+    QEMU_OPTION_watchdog_action,
     QEMU_OPTION_echr,
     QEMU_OPTION_virtiocon,
     QEMU_OPTION_show_cursor,
@@ -4448,6 +4457,8 @@ static const QEMUOption qemu_options[] =
     { "localtime", 0, QEMU_OPTION_localtime },
     { "startdate", HAS_ARG, QEMU_OPTION_startdate },
     { "icount", HAS_ARG, QEMU_OPTION_icount },
+    { "watchdog", HAS_ARG, QEMU_OPTION_watchdog },
+    { "watchdog-action", HAS_ARG, QEMU_OPTION_watchdog_action },
     { "echr", HAS_ARG, QEMU_OPTION_echr },
     { "virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon },
     { "show-cursor", 0, QEMU_OPTION_show_cursor },
@@ -4949,6 +4960,8 @@ int main(int argc, char **argv, char **e
     tb_size = 0;
     autostart= 1;
 
+    register_watchdogs();
+
     optind = 1;
     for(;;) {
         if (optind >= argc)
@@ -5323,6 +5336,17 @@ int main(int argc, char **argv, char **e
                 serial_devices[serial_device_index] = optarg;
                 serial_device_index++;
                 break;
+            case QEMU_OPTION_watchdog:
+                i = select_watchdog(optarg);
+                if (i > 0)
+                    exit (i == 1 ? 1 : 0);
+                break;
+            case QEMU_OPTION_watchdog_action:
+                if (select_watchdog_action(optarg) == -1) {
+                    fprintf(stderr, "Unknown -watchdog-action parameter\n");
+                    exit(1);
+                }
+                break;
             case QEMU_OPTION_virtiocon:
                 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
                     fprintf(stderr, "qemu: too many virtio consoles\n");
@@ -5838,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.3.0-testing/tools/python/xen/xend/XendConstants.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendConstants.py
+++ xen-4.3.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'
Index: xen-4.3.0-testing/tools/python/xen/xend/XendLogging.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendLogging.py
+++ xen-4.3.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"
Index: xen-4.3.0-testing/tools/python/xen/xend/server/XMLRPCServer.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/server/XMLRPCServer.py
+++ xen-4.3.0-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.3.0-testing/tools/qemu-xen-traditional-dir-remote/block_int.h
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block_int.h
+++ xen-4.3.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.3.0-testing/tools/qemu-xen-traditional-dir-remote/block.h
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/block.h
+++ xen-4.3.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);
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.c
===================================================================
--- /dev/null
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.c
@@ -0,0 +1,146 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#include "qemu-common.h"
+#include "sys-queue.h"
+#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)
+{
+    LIST_INSERT_HEAD(&watchdog_list, model, entry);
+}
+
+/* Returns:
+ *   0 = continue
+ *   1 = exit program with error
+ *   2 = exit program without error
+ */
+int select_watchdog(const char *p)
+{
+    WatchdogTimerModel *model;
+
+    if (watchdog) {
+        fprintf(stderr,
+                 "qemu: only one watchdog option may be given\n");
+        return 1;
+    }
+
+    /* -watchdog ? lists available devices and exits cleanly. */
+    if (strcmp(p, "?") == 0) {
+        LIST_FOREACH(model, &watchdog_list, entry) {
+            fprintf(stderr, "\t%s\t%s\n",
+                     model->wdt_name, model->wdt_description);
+        }
+        return 2;
+    }
+
+    LIST_FOREACH(model, &watchdog_list, entry) {
+        if (strcasecmp(model->wdt_name, p) == 0) {
+            watchdog = model;
+            return 0;
+        }
+    }
+
+    fprintf(stderr, "Unknown -watchdog device. Supported devices are:\n");
+    LIST_FOREACH(model, &watchdog_list, entry) {
+        fprintf(stderr, "\t%s\t%s\n",
+                 model->wdt_name, model->wdt_description);
+    }
+    return 1;
+}
+
+int select_watchdog_action(const char *p)
+{
+    if (strcasecmp(p, "reset") == 0)
+        watchdog_action = WDT_RESET;
+    else if (strcasecmp(p, "shutdown") == 0)
+        watchdog_action = WDT_SHUTDOWN;
+    else if (strcasecmp(p, "poweroff") == 0)
+        watchdog_action = WDT_POWEROFF;
+    else if (strcasecmp(p, "pause") == 0)
+        watchdog_action = WDT_PAUSE;
+    else if (strcasecmp(p, "debug") == 0)
+        watchdog_action = WDT_DEBUG;
+    else if (strcasecmp(p, "none") == 0)
+        watchdog_action = WDT_NONE;
+    else
+        return -1;
+
+    return 0;
+}
+
+/* This actually performs the "action" once a watchdog has expired,
+ * ie. reboot, shutdown, exit, etc.
+ */
+void watchdog_perform_action(void)
+{
+    switch(watchdog_action) {
+    case WDT_RESET:             /* same as 'system_reset' in monitor */
+        qemu_system_reset_request();
+        break;
+
+    case WDT_SHUTDOWN:          /* same as 'system_powerdown' in monitor */
+        qemu_system_powerdown_request();
+        break;
+
+    case WDT_POWEROFF:          /* same as 'quit' command in monitor */
+        exit(0);
+        break;
+
+    case WDT_PAUSE:             /* same as 'stop' command in monitor */
+        vm_stop(0);
+        break;
+
+    case WDT_DEBUG:
+        fprintf(stderr, "watchdog: timer fired\n");
+        break;
+
+    case WDT_NONE:
+        break;
+    }
+}
+
+void watchdog_pc_init(PCIBus *pci_bus)
+{
+    if (watchdog)
+        watchdog->wdt_pc_init(pci_bus);
+}
+
+void register_watchdogs(void)
+{
+    wdt_ib700_init();
+    wdt_i6300esb_init();
+}
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.h
===================================================================
--- /dev/null
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/watchdog.h
@@ -0,0 +1,54 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#ifndef QEMU_WATCHDOG_H
+#define QEMU_WATCHDOG_H
+
+extern void wdt_i6300esb_init(void);
+extern void wdt_ib700_init(void);
+
+
+struct WatchdogTimerModel {
+    LIST_ENTRY(WatchdogTimerModel) entry;
+
+    /* Short name of the device - used to select it on the command line. */
+    const char *wdt_name;
+    /* Longer description (eg. manufacturer and full model number). */
+    const char *wdt_description;
+
+    /* This callback should create/register the device.  It is called
+     * indirectly from hw/pc.c when the virtual PC is being set up.
+     */
+    void (*wdt_pc_init)(PCIBus *pci_bus);
+};
+typedef struct WatchdogTimerModel WatchdogTimerModel;
+
+/* in hw/watchdog.c */
+extern int select_watchdog(const char *p);
+extern int select_watchdog_action(const char *action);
+extern void watchdog_add_model(WatchdogTimerModel *model);
+extern void watchdog_perform_action(void);
+extern void watchdog_pc_init(PCIBus *pci_bus);
+extern void register_watchdogs(void);
+
+#endif /* QEMU_WATCHDOG_H */
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/wdt_i6300esb.c
===================================================================
--- /dev/null
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/wdt_i6300esb.c
@@ -0,0 +1,470 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#include <inttypes.h>
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "watchdog.h"
+#include "hw.h"
+#include "isa.h"
+#include "pc.h"
+#include "pci.h"
+
+/*#define I6300ESB_DEBUG 1*/
+
+#ifdef I6300ESB_DEBUG
+#define i6300esb_debug(fs,...) \
+    fprintf(stderr,"i6300esb: %s: "fs,__func__,##__VA_ARGS__)
+#else
+#define i6300esb_debug(fs,...)
+#endif
+
+#ifndef PCI_DEVICE_ID_INTEL_ESB_9
+#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab
+#endif
+
+/* PCI configuration registers */
+#define ESB_CONFIG_REG  0x60            /* Config register                   */
+#define ESB_LOCK_REG    0x68            /* WDT lock register                 */
+
+/* Memory mapped registers (offset from base address) */
+#define ESB_TIMER1_REG  0x00            /* Timer1 value after each reset     */
+#define ESB_TIMER2_REG  0x04            /* Timer2 value after each reset     */
+#define ESB_GINTSR_REG  0x08            /* General Interrupt Status Register */
+#define ESB_RELOAD_REG  0x0c            /* Reload register                   */
+
+/* Lock register bits */
+#define ESB_WDT_FUNC    (0x01 << 2)   /* Watchdog functionality            */
+#define ESB_WDT_ENABLE  (0x01 << 1)   /* Enable WDT                        */
+#define ESB_WDT_LOCK    (0x01 << 0)   /* Lock (nowayout)                   */
+
+/* Config register bits */
+#define ESB_WDT_REBOOT  (0x01 << 5)   /* Enable reboot on timeout          */
+#define ESB_WDT_FREQ    (0x01 << 2)   /* Decrement frequency               */
+#define ESB_WDT_INTTYPE (0x11 << 0)   /* Interrupt type on timer1 timeout  */
+
+/* Reload register bits */
+#define ESB_WDT_RELOAD  (0x01 << 8)    /* prevent timeout                   */
+
+/* Magic constants */
+#define ESB_UNLOCK1     0x80            /* Step 1 to unlock reset registers  */
+#define ESB_UNLOCK2     0x86            /* Step 2 to unlock reset registers  */
+
+/* Device state. */
+struct I6300State {
+    PCIDevice dev;              /* PCI device state, must be first field. */
+
+    int reboot_enabled;         /* "Reboot" on timer expiry.  The real action
+                                 * performed depends on the -watchdog-action
+                                 * param passed on QEMU command line.
+                                 */
+    int clock_scale;            /* Clock scale. */
+#define CLOCK_SCALE_1KHZ 0
+#define CLOCK_SCALE_1MHZ 1
+
+    int int_type;               /* Interrupt type generated. */
+#define INT_TYPE_IRQ 0          /* APIC 1, INT 10 */
+#define INT_TYPE_SMI 2
+#define INT_TYPE_DISABLED 3
+
+    int free_run;               /* If true, reload timer on expiry. */
+    int locked;                 /* If true, enabled field cannot be changed. */
+    int enabled;                /* If true, watchdog is enabled. */
+
+    QEMUTimer *timer;           /* The actual watchdog timer. */
+
+    uint32_t timer1_preload;    /* Values preloaded into timer1, timer2. */
+    uint32_t timer2_preload;
+    int stage;                  /* Stage (1 or 2). */
+
+    int unlock_state;           /* Guest writes 0x80, 0x86 to unlock the
+                                 * registers, and we transition through
+                                 * states 0 -> 1 -> 2 when this happens.
+                                 */
+
+    int previous_reboot_flag;   /* If the watchdog caused the previous
+                                 * reboot, this flag will be set.
+                                 */
+};
+
+typedef struct I6300State I6300State;
+
+/* This function is called when the watchdog has either been enabled
+ * (hence it starts counting down) or has been keep-alived.
+ */
+static void i6300esb_restart_timer(I6300State *d, int stage)
+{
+    int64_t timeout;
+
+    if (!d->enabled)
+        return;
+
+    d->stage = stage;
+
+    if (d->stage <= 1)
+        timeout = d->timer1_preload;
+    else
+        timeout = d->timer2_preload;
+
+    if (d->clock_scale == CLOCK_SCALE_1KHZ)
+        timeout <<= 15;
+    else
+        timeout <<= 5;
+
+    /* Get the timeout in units of ticks_per_sec. */
+    timeout = ticks_per_sec * timeout / 33000000;
+
+    i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);
+
+    qemu_mod_timer(d->timer, qemu_get_clock(vm_clock) + timeout);
+}
+
+/* This is called when the guest disables the watchdog. */
+static void i6300esb_disable_timer(I6300State *d)
+{
+    i6300esb_debug("timer disabled\n");
+
+    qemu_del_timer(d->timer);
+}
+
+static void i6300esb_reset(I6300State *d)
+{
+    /* XXX We should probably reset other parts of the state here,
+     * but we should also reset our state on general machine reset
+     * too.  For now just disable the timer so it doesn't fire
+     * again after the reboot.
+     */
+    i6300esb_disable_timer(d);
+}
+
+/* This function is called when the watchdog expires.  Note that
+ * the hardware has two timers, and so expiry happens in two stages.
+ * If d->stage == 1 then we perform the first stage action (usually,
+ * sending an interrupt) and then restart the timer again for the
+ * second stage.  If the second stage expires then the watchdog
+ * really has run out.
+ */
+static void i6300esb_timer_expired(void *vp)
+{
+    I6300State *d = (I6300State *) vp;
+
+    i6300esb_debug("stage %d\n", d->stage);
+
+    if (d->stage == 1) {
+        /* What to do at the end of stage 1? */
+        switch (d->int_type) {
+        case INT_TYPE_IRQ:
+            fprintf(stderr, "i6300esb_timer_expired: I would send APIC 1 INT 10 here if I knew how (XXX)\n");
+            break;
+        case INT_TYPE_SMI:
+            fprintf(stderr, "i6300esb_timer_expired: I would send SMI here if I knew how (XXX)\n");
+            break;
+        }
+
+        /* Start the second stage. */
+        i6300esb_restart_timer(d, 2);
+    } else {
+        /* Second stage expired, reboot for real. */
+        if (d->reboot_enabled) {
+            d->previous_reboot_flag = 1;
+            watchdog_perform_action(); /* This reboots, exits, etc */
+            i6300esb_reset(d);
+        }
+
+        /* In "free running mode" we start stage 1 again. */
+        if (d->free_run)
+            i6300esb_restart_timer(d, 1);
+    }
+}
+
+static void i6300esb_config_write(PCIDevice *dev, uint32_t addr,
+                                  uint32_t data, int len)
+{
+    I6300State *d = (I6300State *) dev;
+    int old;
+
+    i6300esb_debug("addr = %x, data = %x, len = %d\n", addr, data, len);
+
+    if (addr == ESB_CONFIG_REG && len == 2) {
+        d->reboot_enabled = (data & ESB_WDT_REBOOT) == 0;
+        d->clock_scale =
+            (data & ESB_WDT_FREQ) != 0 ? CLOCK_SCALE_1MHZ : CLOCK_SCALE_1KHZ;
+        d->int_type = (data & ESB_WDT_INTTYPE);
+    } else if (addr == ESB_LOCK_REG && len == 1) {
+        if (!d->locked) {
+            d->locked = (data & ESB_WDT_LOCK) != 0;
+            d->free_run = (data & ESB_WDT_FUNC) != 0;
+            old = d->enabled;
+            d->enabled = (data & ESB_WDT_ENABLE) != 0;
+            if (!old && d->enabled) /* Enabled transitioned from 0 -> 1 */
+                i6300esb_restart_timer(d, 1);
+            else if (!d->enabled)
+                i6300esb_disable_timer(d);
+        }
+    } else {
+        pci_default_write_config(dev, addr, data, len);
+    }
+}
+
+static uint32_t i6300esb_config_read(PCIDevice *dev, uint32_t addr, int len)
+{
+    I6300State *d = (I6300State *) dev;
+    uint32_t data;
+
+    i6300esb_debug ("addr = %x, len = %d\n", addr, len);
+
+    if (addr == ESB_CONFIG_REG && len == 2) {
+        data =
+            (d->reboot_enabled ? 0 : ESB_WDT_REBOOT) |
+            (d->clock_scale == CLOCK_SCALE_1MHZ ? ESB_WDT_FREQ : 0) |
+            d->int_type;
+        return data;
+    } else if (addr == ESB_LOCK_REG && len == 1) {
+        data =
+            (d->free_run ? ESB_WDT_FUNC : 0) |
+            (d->locked ? ESB_WDT_LOCK : 0) |
+            (d->enabled ? ESB_WDT_ENABLE : 0);
+        return data;
+    } else {
+        return pci_default_read_config(dev, addr, len);
+    }
+}
+
+static uint32_t i6300esb_mem_readb(void *vp, target_phys_addr_t addr)
+{
+    i6300esb_debug ("addr = %x\n", (int) addr);
+
+    return 0;
+}
+
+static uint32_t i6300esb_mem_readw(void *vp, target_phys_addr_t addr)
+{
+    uint32_t data = 0;
+    I6300State *d = (I6300State *) vp;
+
+    i6300esb_debug("addr = %x\n", (int) addr);
+
+    if (addr == 0xc) {
+        /* The previous reboot flag is really bit 9, but there is
+         * a bug in the Linux driver where it thinks it's bit 12.
+         * Set both.
+         */
+        data = d->previous_reboot_flag ? 0x1200 : 0;
+    }
+
+    return data;
+}
+
+static uint32_t i6300esb_mem_readl(void *vp, target_phys_addr_t addr)
+{
+    i6300esb_debug("addr = %x\n", (int) addr);
+
+    return 0;
+}
+
+static void i6300esb_mem_writeb(void *vp, target_phys_addr_t addr, uint32_t val)
+{
+    I6300State *d = (I6300State *) vp;
+
+    i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);
+
+    if (addr == 0xc && val == 0x80)
+        d->unlock_state = 1;
+    else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
+        d->unlock_state = 2;
+}
+
+static void i6300esb_mem_writew(void *vp, target_phys_addr_t addr, uint32_t val)
+{
+    I6300State *d = (I6300State *) vp;
+
+    i6300esb_debug("addr = %x, val = %x\n", (int) addr, val);
+
+    if (addr == 0xc && val == 0x80)
+        d->unlock_state = 1;
+    else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
+        d->unlock_state = 2;
+    else {
+        if (d->unlock_state == 2) {
+            if (addr == 0xc) {
+                if ((val & 0x100) != 0)
+                    /* This is the "ping" from the userspace watchdog in
+                     * the guest ...
+                     */
+                    i6300esb_restart_timer(d, 1);
+
+                /* Setting bit 9 resets the previous reboot flag.
+                 * There's a bug in the Linux driver where it sets
+                 * bit 12 instead.
+                 */
+                if ((val & 0x200) != 0 || (val & 0x1000) != 0) {
+                    d->previous_reboot_flag = 0;
+                }
+            }
+
+            d->unlock_state = 0;
+        }
+    }
+}
+
+static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val)
+{
+    I6300State *d = (I6300State *) vp;
+
+    i6300esb_debug ("addr = %x, val = %x\n", (int) addr, val);
+
+    if (addr == 0xc && val == 0x80)
+        d->unlock_state = 1;
+    else if (addr == 0xc && val == 0x86 && d->unlock_state == 1)
+        d->unlock_state = 2;
+    else {
+        if (d->unlock_state == 2) {
+            if (addr == 0)
+                d->timer1_preload = val & 0xfffff;
+            else if (addr == 4)
+                d->timer2_preload = val & 0xfffff;
+
+            d->unlock_state = 0;
+        }
+    }
+}
+
+static void i6300esb_map(PCIDevice *dev, int region_num,
+                         uint32_t addr, uint32_t size, int type)
+{
+    static CPUReadMemoryFunc *mem_read[3] = {
+        i6300esb_mem_readb,
+        i6300esb_mem_readw,
+        i6300esb_mem_readl,
+    };
+    static CPUWriteMemoryFunc *mem_write[3] = {
+        i6300esb_mem_writeb,
+        i6300esb_mem_writew,
+        i6300esb_mem_writel,
+    };
+    I6300State *d = (I6300State *) dev;
+    int io_mem;
+
+    i6300esb_debug("addr = %x, size = %x, type = %d\n", addr, size, type);
+
+    io_mem = cpu_register_io_memory (0, mem_read, mem_write, d);
+    cpu_register_physical_memory (addr, 0x10, io_mem);
+    /* qemu_register_coalesced_mmio (addr, 0x10); ? */
+}
+
+static void i6300esb_save(QEMUFile *f, void *vp)
+{
+    I6300State *d = (I6300State *) vp;
+
+    pci_device_save(&d->dev, f);
+    qemu_put_be32(f, d->reboot_enabled);
+    qemu_put_be32(f, d->clock_scale);
+    qemu_put_be32(f, d->int_type);
+    qemu_put_be32(f, d->free_run);
+    qemu_put_be32(f, d->locked);
+    qemu_put_be32(f, d->enabled);
+    qemu_put_timer(f, d->timer);
+    qemu_put_be32(f, d->timer1_preload);
+    qemu_put_be32(f, d->timer2_preload);
+    qemu_put_be32(f, d->stage);
+    qemu_put_be32(f, d->unlock_state);
+    qemu_put_be32(f, d->previous_reboot_flag);
+}
+
+static int i6300esb_load(QEMUFile *f, void *vp, int version)
+{
+    I6300State *d = (I6300State *) vp;
+
+    if (version != sizeof (I6300State))
+        return -EINVAL;
+
+    pci_device_load(&d->dev, f);
+    d->reboot_enabled = qemu_get_be32(f);
+    d->clock_scale = qemu_get_be32(f);
+    d->int_type = qemu_get_be32(f);
+    d->free_run = qemu_get_be32(f);
+    d->locked = qemu_get_be32(f);
+    d->enabled = qemu_get_be32(f);
+    qemu_get_timer(f, d->timer);
+    d->timer1_preload = qemu_get_be32(f);
+    d->timer2_preload = qemu_get_be32(f);
+    d->stage = qemu_get_be32(f);
+    d->unlock_state = qemu_get_be32(f);
+    d->previous_reboot_flag = qemu_get_be32(f);
+
+    return 0;
+}
+
+/* Create and initialize a virtual Intel 6300ESB during PC creation. */
+static void i6300esb_pc_init(PCIBus *pci_bus)
+{
+    I6300State *d;
+    uint8_t *pci_conf;
+
+    if (!pci_bus) {
+        fprintf(stderr, "wdt_i6300esb: no PCI bus in this machine\n");
+        return;
+    }
+
+    d = (I6300State *)
+        pci_register_device (pci_bus, "i6300esb_wdt", sizeof (I6300State),
+                             -1,
+                             i6300esb_config_read, i6300esb_config_write);
+
+    d->reboot_enabled = 1;
+    d->clock_scale = CLOCK_SCALE_1KHZ;
+    d->int_type = INT_TYPE_IRQ;
+    d->free_run = 0;
+    d->locked = 0;
+    d->enabled = 0;
+    d->timer = qemu_new_timer(vm_clock, i6300esb_timer_expired, d);
+    d->timer1_preload = 0xfffff;
+    d->timer2_preload = 0xfffff;
+    d->stage = 1;
+    d->unlock_state = 0;
+    d->previous_reboot_flag = 0;
+
+    pci_conf = d->dev.config;
+    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
+    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_ESB_9);
+    pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER);
+    pci_conf[0x0e] = 0x00;
+
+    pci_register_io_region(&d->dev, 0, 0x10,
+                            PCI_ADDRESS_SPACE_MEM, i6300esb_map);
+
+    register_savevm("i6300esb_wdt", -1, sizeof(I6300State),
+                     i6300esb_save, i6300esb_load, d);
+}
+
+static WatchdogTimerModel model = {
+    .wdt_name = "i6300esb",
+    .wdt_description = "Intel 6300ESB",
+    .wdt_pc_init = i6300esb_pc_init,
+};
+
+void wdt_i6300esb_init(void)
+{
+    watchdog_add_model(&model);
+}
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/wdt_ib700.c
===================================================================
--- /dev/null
+++ xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/wdt_ib700.c
@@ -0,0 +1,112 @@
+/*
+ * Virtual hardware watchdog.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+ * USA.
+ *
+ * By Richard W.M. Jones (rjones@redhat.com).
+ */
+
+#include "qemu-common.h"
+#include "qemu-timer.h"
+#include "watchdog.h"
+#include "hw.h"
+#include "isa.h"
+#include "pc.h"
+
+/*#define IB700_DEBUG 1*/
+
+#ifdef IB700_DEBUG
+#define ib700_debug(fs,...)					\
+    fprintf(stderr,"ib700: %s: "fs,__func__,##__VA_ARGS__)
+#else
+#define ib700_debug(fs,...)
+#endif
+
+/* This is the timer.  We use a global here because the watchdog
+ * code ensures there is only one watchdog (it is located at a fixed,
+ * unchangable IO port, so there could only ever be one anyway).
+ */
+static QEMUTimer *timer = NULL;
+
+/* A write to this register enables the timer. */
+static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data)
+{
+    static int time_map[] = {
+        30, 28, 26, 24, 22, 20, 18, 16,
+        14, 12, 10,  8,  6,  4,  2,  0
+    };
+    int64 timeout;
+
+    ib700_debug("addr = %x, data = %x\n", addr, data);
+
+    timeout = (int64_t) time_map[data & 0xF] * ticks_per_sec;
+    qemu_mod_timer(timer, qemu_get_clock (vm_clock) + timeout);
+}
+
+/* A write (of any value) to this register disables the timer. */
+static void ib700_write_disable_reg(void *vp, uint32_t addr, uint32_t data)
+{
+    ib700_debug("addr = %x, data = %x\n", addr, data);
+
+    qemu_del_timer(timer);
+}
+
+/* This is called when the watchdog expires. */
+static void ib700_timer_expired(void *vp)
+{
+    ib700_debug("watchdog expired\n");
+
+    watchdog_perform_action();
+    qemu_del_timer(timer);
+}
+
+static void ib700_save(QEMUFile *f, void *vp)
+{
+    qemu_put_timer(f, timer);
+}
+
+static int ib700_load(QEMUFile *f, void *vp, int version)
+{
+    if (version != 0)
+        return -EINVAL;
+
+    qemu_get_timer(f, timer);
+
+    return 0;
+}
+
+/* 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);
+    register_ioport_write(0x443, 2, 1, ib700_write_enable_reg, NULL);
+}
+
+static WatchdogTimerModel model = {
+    .wdt_name = "ib700",
+    .wdt_description = "iBASE 700",
+    .wdt_pc_init = ib700_pc_init,
+};
+
+void wdt_ib700_init(void)
+{
+    watchdog_add_model(&model);
+}
Index: xen-4.3.0-testing/tools/libxl/libxl_dm.c
===================================================================
--- xen-4.3.0-testing.orig/tools/libxl/libxl_dm.c
+++ xen-4.3.0-testing/tools/libxl/libxl_dm.c
@@ -220,6 +220,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);
         }
@@ -507,6 +513,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);
         }
Index: xen-4.3.0-testing/tools/libxl/libxl_types.idl
===================================================================
--- xen-4.3.0-testing.orig/tools/libxl/libxl_types.idl
+++ xen-4.3.0-testing/tools/libxl/libxl_types.idl
@@ -332,6 +332,8 @@ libxl_domain_build_info = Struct("domain
                                        ("soundhw",          string),
                                        ("xen_platform_pci", libxl_defbool),
                                        ("usbdevice_list",   libxl_string_list),
+                                       ("watchdog",         string),
+                                       ("watchdog_action",  string),
                                        ])),
                  ("pv", Struct(None, [("kernel", string),
                                       ("slack_memkb", MemKB),
Index: xen-4.3.0-testing/tools/libxl/xl_cmdimpl.c
===================================================================
--- xen-4.3.0-testing.orig/tools/libxl/xl_cmdimpl.c
+++ xen-4.3.0-testing/tools/libxl/xl_cmdimpl.c
@@ -1516,6 +1516,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
Index: xen-4.3.0-testing/tools/python/xen/xm/cpupool.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xm/cpupool.py
+++ xen-4.3.0-testing/tools/python/xen/xm/cpupool.py
@@ -157,9 +157,17 @@ def make_cpus_config(cfg_cpus):
             #    ["0,2","1,3"]       -> [[0,2],[1,3]]
             #    ["0-3,^1","1-4,^2"] -> [[0,2,3],[1,3,4]]
             try:
-                for c in cfg_cpus:
-                    cpus = cnv(c)
-                    cpus_list.append(cpus)
+                cpus_str = ""
+                list_len = len(cfg_cpus)
+                n = 0
+                while n < list_len:
+                    if type(cfg_cpus[n]) != str:
+                        raise SyntaxError('cpus = %s' % cfg_cpus)
+                    cpus_str += cfg_cpus[n]
+                    n += 1
+                    if n < list_len:
+                        cpus_str += ', '
+                cpus_list = cnv(cpus_str)
             except ValueError, e:
                 raise err('cpus = %s: %s' % (cfg_cpus, e))
     else:
Index: xen-4.3.0-testing/tools/python/xen/xend/server/netif.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/server/netif.py
+++ xen-4.3.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"""
 
Index: xen-4.3.0-testing/tools/python/xen/util/pci.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/util/pci.py
+++ xen-4.3.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.3.0-testing/tools/python/xen/xend/server/pciif.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/server/pciif.py
+++ xen-4.3.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):
Index: xen-4.3.0-testing/tools/python/xen/lowlevel/xc/xc.c
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/lowlevel/xc/xc.c
+++ xen-4.3.0-testing/tools/python/xen/lowlevel/xc/xc.c
@@ -954,18 +954,23 @@ static PyObject *pyxc_hvm_build(XcObject
     struct hvm_info_table *va_hvm;
     uint8_t *va_map, sum;
 #endif
-    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));
@@ -996,8 +1001,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);
 
 #if !defined(__ia64__)
Index: xen-4.3.0-testing/tools/python/README.sxpcfg
===================================================================
--- xen-4.3.0-testing.orig/tools/python/README.sxpcfg
+++ xen-4.3.0-testing/tools/python/README.sxpcfg
@@ -51,6 +51,11 @@ image
   - vncunused
   (HVM)
   - device_model
+  - actmem
+  - xenpaging_file
+  - xenpaging_extra
+  - smbios_firmware
+  - acpi_firmware
   - display
   - xauthority
   - vncconsole
Index: xen-4.3.0-testing/tools/python/README.XendConfig
===================================================================
--- xen-4.3.0-testing.orig/tools/python/README.XendConfig
+++ xen-4.3.0-testing/tools/python/README.XendConfig
@@ -118,6 +118,11 @@ 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
                                 image.hvm.xauthority
                                 image.hvm.vncconsole
Index: xen-4.3.0-testing/tools/hotplug/Linux/domain-lock
===================================================================
--- /dev/null
+++ xen-4.3.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] -i <vm uuid> 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.3.0-testing/tools/hotplug/Linux/vm-monitor
===================================================================
--- /dev/null
+++ xen-4.3.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.3.0-testing/tools/python/xen/xend/XendOptions.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/XendOptions.py
+++ xen-4.3.0-testing/tools/python/xen/xend/XendOptions.py
@@ -154,6 +154,20 @@ 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"
+
+    """Default block device for lock service"""
+    xend_domain_lock_device = ""
+
+
     def __init__(self):
         self.configure()
 
@@ -401,6 +415,26 @@ 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_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)
Index: xen-4.3.0-testing/tools/hotplug/Linux/domain-lock-sfex
===================================================================
--- /dev/null
+++ xen-4.3.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.3.0-testing/tools/python/xen/xend/server/BlktapController.py
===================================================================
--- xen-4.3.0-testing.orig/tools/python/xen/xend/server/BlktapController.py
+++ xen-4.3.0-testing/tools/python/xen/xend/server/BlktapController.py
@@ -15,6 +15,7 @@ blktap1_disk_types = [
     'ram',
     'qcow',
     'qcow2',
+    'cdrom',
     'ioemu',
     ]
 
Index: xen-4.3.0-testing/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/qemu-xen.h
+++ xen-4.3.0-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;
@@ -47,6 +49,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);
 
@@ -64,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.3.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pci.c
===================================================================
--- xen-4.3.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pci.c
+++ xen-4.3.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.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
@@ -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/<domain_name>.<domaind_id>.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
openSUSE Build Service is sponsored by