This patch make xm reboot/shutdown work for vmx doamin.
authorKe Yu <ke.yu@intel.com>
Tue, 24 Jan 2006 16:58:43 +0000 (17:58 +0100)
committerKe Yu <ke.yu@intel.com>
Tue, 24 Jan 2006 16:58:43 +0000 (17:58 +0100)
xm reboot fails due to two issues:
1. no mechanism to change XendDomainInfo.info to trigger domain reboot
2. ioemu blkif parameter is missing during reboot, thus device model recreation will fail.

This patch fix these issues by
1. introducing a xswatch to monitor the control/shutdown node. once fired, it will change the XendDomainInfo.info to trigger domain reboot
2. saving the ioemu blkif parameter in xen store just like DomU does.

Signed-off-by: Yu Ke <ke.yu@intel.com>
tools/python/xen/xend/image.py
tools/python/xen/xend/server/blkif.py

index e50c2b4c3cf704588d2266ca9afcb3960a1ab6ce..338a1006eb358a0451876f1d9df170214f74baaa 100644 (file)
@@ -25,6 +25,7 @@ from xen.xend import sxp
 from xen.xend.XendError import VmError
 from xen.xend.XendLogging import log
 from xen.xend.server.netif import randomMAC
+from xen.xend.xenstore.xswatch import xswatch
 
 
 xc = xen.lowlevel.xc.xc()
@@ -229,6 +230,8 @@ class VmxImageHandler(ImageHandler):
         log.debug("acpi           = %d", self.acpi)
         log.debug("apic           = %d", self.apic)
 
+        self.register_shutdown_watch()
+
         return xc.vmx_build(dom            = self.vm.getDomid(),
                             image          = self.kernel,
                             control_evtchn = self.device_channel,
@@ -365,6 +368,7 @@ class VmxImageHandler(ImageHandler):
         return vncconnect
 
     def destroy(self):
+        self.unregister_shutdown_watch();
         import signal
         if not self.pid:
             return
@@ -398,6 +402,41 @@ class VmxImageHandler(ImageHandler):
         else:
             return 1 + ((mem_mb + 3) >> 2)
 
+    def register_shutdown_watch(self):
+        """ add xen store watch on control/shutdown """
+        self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \
+                                    self.vmx_shutdown)
+        log.debug("vmx shutdown watch registered")
+
+    def unregister_shutdown_watch(self):
+        """Remove the watch on the control/shutdown, if any. Nothrow
+        guarantee."""
+
+        try:
+            if self.shutdownWatch:
+                self.shutdownWatch.unwatch()
+        except:
+            log.exception("Unwatching vmx shutdown watch failed.")
+        self.shutdownWatch = None
+        log.debug("vmx shutdown watch unregistered")
+
+    def vmx_shutdown(self, _):
+        """ watch call back on node control/shutdown,
+            if node changed, this function will be called
+        """
+        from xen.xend.XendDomainInfo import shutdown_reasons
+        xd = xen.xend.XendDomain.instance()
+        vm = xd.domain_lookup( self.vm.getDomid() )
+
+        reason = vm.readDom('control/shutdown')
+        log.debug("vmx_shutdown fired, shutdown reason=%s", reason)
+        for x in shutdown_reasons.keys():
+            if shutdown_reasons[x] == reason:
+                vm.info['shutdown'] = 1
+                vm.info['shutdown_reason'] = x
+                vm.refreshShutdown(vm.info)
+
+        return 1 # Keep watching
 
 """Table of image handler classes for virtual machine images.  Indexed by
 image type.
index 23135aa08bf2490063b2e9ca6a2b4b19cef6f879..02cd4f26f7d671dbd32cd6479df37f928bb048ce 100644 (file)
@@ -42,10 +42,6 @@ class BlkifController(DevController):
         """@see DevController.getDeviceDetails"""
 
         dev = sxp.child_value(config, 'dev')
-        if 'ioemu:' in dev:
-            return (None,{},{})
-
-        devid = blkif.blkdev_name_to_number(dev)
 
         (typ, params) = string.split(sxp.child_value(config, 'uname'), ':', 1)
         back = { 'dev'    : dev,
@@ -54,7 +50,13 @@ class BlkifController(DevController):
                  'mode'   : sxp.child_value(config, 'mode', 'r')
                  }
 
-        front = { 'virtual-device' : "%i" % devid }
+        if 'ioemu:' in dev:
+            (dummy, dev1) = string.split(dev, ':', 1)
+            devid = blkif.blkdev_name_to_number(dev1)
+            front = {}
+        else:
+            devid = blkif.blkdev_name_to_number(dev)
+            front = { 'virtual-device' : "%i" % devid }
 
         return (devid, back, front)