WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] PATCH: 9/10: XenD device model re-factoring

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: Re: [Xen-devel] PATCH: 9/10: XenD device model re-factoring
From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>
Date: Wed, 22 Aug 2007 23:33:15 +0100
Delivery-date: Wed, 22 Aug 2007 15:34:48 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20070822222653.GR18061@xxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20070822222653.GR18061@xxxxxxxxxx>
Reply-to: "Daniel P. Berrange" <berrange@xxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.4.1i
This patches adapts XenD so that it is capable of starting a qemu-dm device
model for both paravirt and fullyvirt guests. A paravirt guest will only be
given a device model if it has a VFB configured, or the user explicitly
include the device_model option in the config config. This avoids unneccessary
overhead for those wanting a minimal paravirt guest.

The bulk of this patch involves moving code from the HVMImageHandler into the
base ImageHandler class. The HVMImageHandler and LinuxImageHandler subclasses
now merely containing a couple of overrides to set some specific command line
flags. The most important is -M xenpv, vs -M xenfv.

The XenConfig class has a minor refactoring to add a has_rfb() method to avoid
duplicating code in a couple of places. Instead of hardcoding DEFAULT_DM it
now uses the xen.util.auxbin APIs to locate it - this works on platforms where
qemu-dm is in /usr/lib64 instead of /usr/lib. As before paravirt only gets a
default qemu-dm if using a VFB

The vfbif.py class is trimmed out since it no longer needs to spawn a daemon.
A few other misc fixes deal with qemu-dm interactions when saving/restoring,
and in particular recovering from save failures (or checkpointing).

 XendCheckpoint.py |    5 
 XendConfig.py     |   35 ++--
 XendDomainInfo.py |   34 ++--
 image.py          |  379 ++++++++++++++++++++++++++++--------------------------
 server/vfbif.py   |  110 ++-------------
 5 files changed, 254 insertions(+), 309 deletions(-)


   Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>

Dan.


diff -r 912986c9283d tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/XendCheckpoint.py   Wed Aug 22 16:17:49 2007 -0400
@@ -6,6 +6,7 @@
 # this archive for more details.
 
 import os
+import os.path
 import re
 import string
 import threading
@@ -105,7 +106,7 @@ def save(fd, dominfo, network, live, dst
         forkHelper(cmd, fd, saveInputHandler, False)
 
         # put qemu device model state
-        if hvm:
+        if os.path.exists("/var/lib/xen/qemu-save.%d" % dominfo.getDomid()):
             write_exact(fd, QEMU_SIGNATURE, "could not write qemu signature")
             qemu_fd = os.open("/var/lib/xen/qemu-save.%d" % dominfo.getDomid(),
                               os.O_RDONLY)
@@ -231,6 +232,8 @@ def restore(xd, fd, dominfo = None, paus
             raise XendError('Could not read console MFN')        
 
         # get qemu state and create a tmp file for dm restore
+        # Even PV guests may have QEMU stat, but its not currently
+        # used so only bother with HVM currently.
         if is_hvm:
             qemu_signature = read_exact(fd, len(QEMU_SIGNATURE),
                                         "invalid device model signature read")
diff -r 912986c9283d tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/XendConfig.py       Wed Aug 22 16:17:49 2007 -0400
@@ -32,6 +32,7 @@ from xen.util.blkif import blkdev_name_t
 from xen.util.blkif import blkdev_name_to_number
 from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
 from xen.util import xsconstants
+import xen.util.auxbin
 
 log = logging.getLogger("xend.XendConfig")
 log.setLevel(logging.WARN)
@@ -236,8 +237,6 @@ LEGACY_XENSTORE_VM_PARAMS = [
     'on_xend_start',
     'on_xend_stop',
 ]
-
-DEFAULT_DM = '/usr/lib/xen/bin/qemu-dm'
 
 ##
 ## Config Choices
@@ -398,13 +397,14 @@ class XendConfig(dict):
             self['name_label'] = 'Domain-' + self['uuid']
 
     def _platform_sanity_check(self):
+        if 'keymap' not in self['platform'] and 
XendOptions.instance().get_keymap():
+            self['platform']['keymap'] = XendOptions.instance().get_keymap()
+
+        if self.is_hvm() or self.has_rfb():
+            if 'device_model' not in self['platform']:
+                self['platform']['device_model'] = 
xen.util.auxbin.pathTo("qemu-dm")
+
         if self.is_hvm():
-            if 'keymap' not in self['platform'] and 
XendOptions.instance().get_keymap():
-                self['platform']['keymap'] = 
XendOptions.instance().get_keymap()
-
-            if 'device_model' not in self['platform']:
-                self['platform']['device_model'] = DEFAULT_DM
-
             # Compatibility hack, can go away soon.
             if 'soundhw' not in self['platform'] and \
                self['platform'].get('enable_audio'):
@@ -740,16 +740,7 @@ class XendConfig(dict):
         # coalesce hvm vnc frame buffer with vfb config
         if self.is_hvm() and int(self['platform'].get('vnc', 0)) != 0:
             # add vfb device if it isn't there already
-            has_rfb = False
-            for console_uuid in self['console_refs']:
-                if self['devices'][console_uuid][1].get('protocol') == 'rfb':
-                    has_rfb = True
-                    break
-                if self['devices'][console_uuid][0] == 'vfb':
-                    has_rfb = True
-                    break
-
-            if not has_rfb:
+            if not self.has_rfb():
                 dev_config = ['vfb']
                 # copy VNC related params from platform config to vfb dev conf
                 for key in ['vncpasswd', 'vncunused', 'vncdisplay',
@@ -759,6 +750,14 @@ class XendConfig(dict):
 
                 self.device_add('vfb', cfg_sxp = dev_config)
 
+
+    def has_rfb(self):
+        for console_uuid in self['console_refs']:
+            if self['devices'][console_uuid][1].get('protocol') == 'rfb':
+                return True
+            if self['devices'][console_uuid][0] == 'vfb':
+                return True
+        return False
 
     def _sxp_to_xapi_unsupported(self, sxp_cfg):
         """Read in an SXP configuration object and populate
diff -r 912986c9283d tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/XendDomainInfo.py   Wed Aug 22 16:20:05 2007 -0400
@@ -1347,10 +1347,16 @@ class XendDomainInfo:
 
     def _releaseDevices(self, suspend = False):
         """Release all domain's devices.  Nothrow guarantee."""
-        if suspend and self.image:
-            self.image.destroy(suspend)
-            return
-
+        if self.image:
+            try:
+                log.debug("Destroying device model")
+                self.image.destroyDeviceModel()
+            except Exception, e:
+                log.exception("Device model destroy failed %s" % str(e))
+        else:
+            log.debug("No device model")
+
+        log.debug("Releasing devices")
         t = xstransact("%s/device" % self.dompath)
         for devclass in XendDevices.valid_devices():
             for dev in t.list(devclass):
@@ -1360,8 +1366,8 @@ class XendDomainInfo:
                 except:
                     # Log and swallow any exceptions in removal --
                     # there's nothing more we can do.
-                        log.exception("Device release failed: %s; %s; %s",
-                                      self.info['name_label'], devclass, dev)
+                    log.exception("Device release failed: %s; %s; %s",
+                                  self.info['name_label'], devclass, dev)
 
             
 
@@ -1586,11 +1592,6 @@ class XendDomainInfo:
             bootloader_tidy(self)
 
             if self.image:
-                try:
-                    self.image.destroy()
-                except:
-                    log.exception(
-                        "XendDomainInfo.cleanup: image.destroy() failed.")
                 self.image = None
 
             try:
@@ -1638,10 +1639,9 @@ class XendDomainInfo:
         self.console_mfn = console_mfn
 
         self._introduceDomain()
-        if self.info.is_hvm():
-            self.image = image.create(self, self.info)
-            if self.image:
-                self.image.createDeviceModel(True)
+        self.image = image.create(self, self.info)
+        if self.image:
+            self.image.createDeviceModel(True)
         self._storeDomDetails()
         self._registerWatches()
         self.refreshShutdown()
@@ -1758,8 +1758,8 @@ class XendDomainInfo:
             ResumeDomain(self.domid)
         except:
             log.exception("XendDomainInfo.resume: xc.domain_resume failed on 
domain %s." % (str(self.domid)))
-        if self.is_hvm():
-            self.image.resumeDeviceModel()
+        self.image.resumeDeviceModel()
+        log.debug("XendDomainInfo.resumeDomain: completed")
 
 
     #
diff -r 912986c9283d tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py    Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/image.py    Wed Aug 22 16:17:49 2007 -0400
@@ -56,10 +56,9 @@ class ImageHandler:
     defining in a subclass.
 
     The method createDeviceModel() is called to create the domain device
-    model if it needs one.  The default is to do nothing.
-
-    The method destroy() is called when the domain is destroyed.
-    The default is to do nothing.
+    model.
+
+    The method destroyDeviceModel() is called to reap the device model
     """
 
     ostype = None
@@ -91,6 +90,15 @@ class ImageHandler:
                         ("image/cmdline", self.cmdline),
                         ("image/ramdisk", self.ramdisk))
 
+        self.dmargs = self.parseDeviceModelArgs(vmConfig)
+        self.device_model = vmConfig['platform'].get('device_model')
+
+        self.display = vmConfig['platform'].get('display')
+        self.xauthority = vmConfig['platform'].get('xauthority')
+        self.vncconsole = vmConfig['platform'].get('vncconsole')
+        self.pid = None
+
+
 
     def cleanupBootloading(self):
         if self.bootloader:
@@ -173,25 +181,145 @@ class ImageHandler:
         """Build the domain. Define in subclass."""
         raise NotImplementedError()
 
+    # Return a list of cmd line args to the device models based on the
+    # xm config file
+    def parseDeviceModelArgs(self, vmConfig):
+        ret = ["-domain-name", str(self.vm.info['name_label'])]
+
+        # Find RFB console device, and if it exists, make QEMU enable
+        # the VNC console.
+        if int(vmConfig['platform'].get('nographic', 0)) != 0:
+            # skip vnc init if nographic is set
+            ret.append('-nographic')
+            return ret
+
+        vnc_config = {}
+        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
+        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
+        for dev_uuid in vmConfig['console_refs']:
+            dev_type, dev_info = vmConfig['devices'][dev_uuid]
+            if dev_type == 'vfb':
+                vnc_config = dev_info.get('other_config', {})
+                has_vnc = True
+                break
+
+        keymap = vmConfig['platform'].get("keymap")
+        if keymap:
+            ret.append("-k")
+            ret.append(keymap)
+
+        if has_vnc:
+            if not vnc_config:
+                for key in ('vncunused', 'vnclisten', 'vncdisplay',
+                            'vncpasswd'):
+                    if key in vmConfig['platform']:
+                        vnc_config[key] = vmConfig['platform'][key]
+
+            vnclisten = vnc_config.get('vnclisten',
+                                       xenopts().get_vnclisten_address())
+            vncdisplay = vnc_config.get('vncdisplay', 0)
+            ret.append('-vnc')
+            ret.append("%s:%d" % (vnclisten, vncdisplay))
+            
+            if vnc_config.get('vncunused', 0):
+                ret.append('-vncunused')
+
+            # Store vncpassword in xenstore
+            vncpasswd = vnc_config.get('vncpasswd')
+            if not vncpasswd:
+                vncpasswd = xenopts().get_vncpasswd_default()
+
+            if vncpasswd is None:
+                raise VmError('vncpasswd is not setup in vmconfig or '
+                              'xend-config.sxp')
+
+            if vncpasswd != '':
+                self.vm.storeVm('vncpasswd', vncpasswd)
+        elif has_sdl:
+            # SDL is default in QEMU.
+            pass
+        else:
+            ret.append('-nographic')
+
+        if int(vmConfig['platform'].get('monitor', 0)) != 0:
+            ret = ret + ['-monitor', 'vc']
+        return ret
+
+    def getDeviceModelArgs(self, restore = False):
+        args = [self.device_model]
+        args = args + ([ "-d",  "%d" % self.vm.getDomid() ])
+        args = args + self.dmargs
+        return args
+
     def createDeviceModel(self, restore = False):
-        """Create device model for the domain (define in subclass if 
needed)."""
-        pass
-    
+        if self.device_model is None:
+            return
+        if self.pid:
+            return
+        # Execute device model.
+        #todo: Error handling
+        args = self.getDeviceModelArgs(restore)
+        env = dict(os.environ)
+        if self.display:
+            env['DISPLAY'] = self.display
+        if self.xauthority:
+            env['XAUTHORITY'] = self.xauthority
+        if self.vncconsole:
+            args = args + ([ "-vncviewer" ])
+        log.info("spawning device models: %s %s", self.device_model, args)
+        # keep track of pid and spawned options to kill it later
+        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
+        self.vm.storeDom("image/device-model-pid", self.pid)
+        log.info("device model pid: %d", self.pid)
+
     def saveDeviceModel(self):
-        """Save device model for the domain (define in subclass if needed)."""
-        pass
+        if self.device_model is None:
+            return
+        # Signal the device model to pause itself and save its state
+        xstransact.Store("/local/domain/0/device-model/%i"
+                         % self.vm.getDomid(), ('command', 'save'))
+        # Wait for confirmation.  Could do this with a watch but we'd
+        # still end up spinning here waiting for the watch to fire. 
+        state = ''
+        count = 0
+        while state != 'paused':
+            state = xstransact.Read("/local/domain/0/device-model/%i/state"
+                                    % self.vm.getDomid())
+            time.sleep(0.1)
+            count += 1
+            if count > 100:
+                raise VmError('Timed out waiting for device model to save')
 
     def resumeDeviceModel(self):
-        """Unpause device model for the domain (define in subclass if 
needed)."""
-        pass
-
-    def destroy(self):
-        """Extra cleanup on domain destroy (define in subclass if needed)."""
-        pass
-
+        if self.device_model is None:
+            return
+        # Signal the device model to resume activity after pausing to save.
+        xstransact.Store("/local/domain/0/device-model/%i"
+                         % self.vm.getDomid(), ('command', 'continue'))
 
     def recreate(self):
-        pass
+        if self.device_model is None:
+            return
+        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
+
+    def destroyDeviceModel(self):
+        if self.device_model is None:
+            return
+        if self.pid:
+            try:
+                os.kill(self.pid, signal.SIGKILL)
+            except OSError, exn:
+                log.exception(exn)
+            try:
+                os.waitpid(self.pid, 0)
+            except OSError, exn:
+                # 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.
+                pass
+            self.pid = None
+            state = xstransact.Remove("/local/domain/0/device-model/%i"
+                                      % self.vm.getDomid())
 
 
 class LinuxImageHandler(ImageHandler):
@@ -223,6 +351,19 @@ class LinuxImageHandler(ImageHandler):
                               ramdisk        = self.ramdisk,
                               features       = self.vm.getFeatures())
 
+    def parseDeviceModelArgs(self, vmConfig):
+        ret = ImageHandler.parseDeviceModelArgs(self, vmConfig)
+        # Equivalent to old xenconsoled behaviour. Should make
+        # it configurable in future
+        ret = ret + ["-serial", "pty"]
+        return ret
+
+    def getDeviceModelArgs(self, restore = False):
+        args = ImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-M", "xenpv"])
+        return args
+
+
 class PPC_LinuxImageHandler(LinuxImageHandler):
 
     ostype = "linux"
@@ -256,15 +397,6 @@ class HVMImageHandler(ImageHandler):
         if 'hvm' not in info['xen_caps']:
             raise HVMRequired()
 
-        self.dmargs = self.parseDeviceModelArgs(vmConfig)
-        self.device_model = vmConfig['platform'].get('device_model')
-        if not self.device_model:
-            raise VmError("hvm: missing device model")
-        
-        self.display = vmConfig['platform'].get('display')
-        self.xauthority = vmConfig['platform'].get('xauthority')
-        self.vncconsole = vmConfig['platform'].get('vncconsole')
-
         rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset')
 
         self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
@@ -272,46 +404,17 @@ class HVMImageHandler(ImageHandler):
                         ("image/display", self.display))
         self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset))
 
-        self.pid = None
-
         self.pae  = int(vmConfig['platform'].get('pae',  0))
         self.apic = int(vmConfig['platform'].get('apic', 0))
         self.acpi = int(vmConfig['platform'].get('acpi', 0))
-        
-
-    def buildDomain(self):
-        store_evtchn = self.vm.getStorePort()
-
-        mem_mb = self.getRequiredInitialReservation() / 1024
-
-        log.debug("domid          = %d", self.vm.getDomid())
-        log.debug("image          = %s", self.kernel)
-        log.debug("store_evtchn   = %d", store_evtchn)
-        log.debug("memsize        = %d", mem_mb)
-        log.debug("vcpus          = %d", self.vm.getVCpuCount())
-        log.debug("pae            = %d", self.pae)
-        log.debug("acpi           = %d", self.acpi)
-        log.debug("apic           = %d", self.apic)
-
-        rc = xc.hvm_build(domid          = self.vm.getDomid(),
-                          image          = self.kernel,
-                          store_evtchn   = store_evtchn,
-                          memsize        = mem_mb,
-                          vcpus          = self.vm.getVCpuCount(),
-                          pae            = self.pae,
-                          acpi           = self.acpi,
-                          apic           = self.apic)
-        rc['notes'] = { 'SUSPEND_CANCEL': 1 }
-        return rc
-
-    # Return a list of cmd line args to the device models based on the
-    # xm config file
+
     def parseDeviceModelArgs(self, vmConfig):
+        ret = ImageHandler.parseDeviceModelArgs(self, vmConfig)
+        ret = ret + ['-vcpus', str(self.vm.getVCpuCount())]
+
         dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
                    'localtime', 'serial', 'stdvga', 'isa',
-                   'acpi', 'usb', 'usbdevice', 'keymap' ]
-        
-        ret = ['-vcpus', str(self.vm.getVCpuCount())]
+                   'acpi', 'usb', 'usbdevice' ]
 
         for a in dmargs:
             v = vmConfig['platform'].get(a)
@@ -340,7 +443,6 @@ class HVMImageHandler(ImageHandler):
 
         # Handle disk/network related options
         mac = None
-        ret = ret + ["-domain-name", str(self.vm.info['name_label'])]
         nics = 0
         
         for devuuid in vmConfig['vbd_refs']:
@@ -369,130 +471,40 @@ class HVMImageHandler(ImageHandler):
             ret.append("-net")
             ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
 
-
-        #
-        # Find RFB console device, and if it exists, make QEMU enable
-        # the VNC console.
-        #
-        if int(vmConfig['platform'].get('nographic', 0)) != 0:
-            # skip vnc init if nographic is set
-            ret.append('-nographic')
-            return ret
-
-        vnc_config = {}
-        has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
-        has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
-        for dev_uuid in vmConfig['console_refs']:
-            dev_type, dev_info = vmConfig['devices'][dev_uuid]
-            if dev_type == 'vfb':
-                vnc_config = dev_info.get('other_config', {})
-                has_vnc = True
-                break
-
-        if has_vnc:
-            if not vnc_config:
-                for key in ('vncunused', 'vnclisten', 'vncdisplay',
-                            'vncpasswd'):
-                    if key in vmConfig['platform']:
-                        vnc_config[key] = vmConfig['platform'][key]
-
-            vnclisten = vnc_config.get('vnclisten',
-                                       xenopts().get_vnclisten_address())
-            vncdisplay = vnc_config.get('vncdisplay', 0)
-            ret.append('-vnc')
-            ret.append("%s:%d" % (vnclisten, vncdisplay))
-            
-            if vnc_config.get('vncunused', 0):
-                ret.append('-vncunused')
-
-            # Store vncpassword in xenstore
-            vncpasswd = vnc_config.get('vncpasswd')
-            if not vncpasswd:
-                vncpasswd = xenopts().get_vncpasswd_default()
-
-            if vncpasswd is None:
-                raise VmError('vncpasswd is not setup in vmconfig or '
-                              'xend-config.sxp')
-
-            if vncpasswd != '':
-                self.vm.storeVm('vncpasswd', vncpasswd)
-        elif has_sdl:
-            # SDL is default in QEMU.
-            pass
-        else:
-            ret.append('-nographic')
-
-        if int(vmConfig['platform'].get('monitor', 0)) != 0:
-            ret = ret + ['-monitor', 'vc']
         return ret
 
-    def createDeviceModel(self, restore = False):
-        if self.pid:
-            return
-        # Execute device model.
-        #todo: Error handling
-        args = [self.device_model]
-        args = args + ([ "-d",  "%d" % self.vm.getDomid() ])
-        if arch.type == "ia64":
-            args = args + ([ "-m", "%s" %
-                             (self.getRequiredInitialReservation() / 1024) ])
-        args = args + self.dmargs
+    def getDeviceModelArgs(self, restore = False):
+        args = ImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-M", "xenfv"])
         if restore:
             args = args + ([ "-loadvm", "/var/lib/xen/qemu-save.%d" %
                              self.vm.getDomid() ])
-        env = dict(os.environ)
-        if self.display:
-            env['DISPLAY'] = self.display
-        if self.xauthority:
-            env['XAUTHORITY'] = self.xauthority
-        if self.vncconsole:
-            args = args + ([ "-vncviewer" ])
-        log.info("spawning device models: %s %s", self.device_model, args)
-        # keep track of pid and spawned options to kill it later
-        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
-        self.vm.storeDom("image/device-model-pid", self.pid)
-        log.info("device model pid: %d", self.pid)
-
-    def saveDeviceModel(self):
-        # Signal the device model to pause itself and save its state
-        xstransact.Store("/local/domain/0/device-model/%i"
-                         % self.vm.getDomid(), ('command', 'save'))
-        # Wait for confirmation.  Could do this with a watch but we'd
-        # still end up spinning here waiting for the watch to fire. 
-        state = ''
-        count = 0
-        while state != 'paused':
-            state = xstransact.Read("/local/domain/0/device-model/%i/state"
-                                    % self.vm.getDomid())
-            time.sleep(0.1)
-            count += 1
-            if count > 100:
-                raise VmError('Timed out waiting for device model to save')
-
-    def resumeDeviceModel(self):
-        # Signal the device model to resume activity after pausing to save.
-        xstransact.Store("/local/domain/0/device-model/%i"
-                         % self.vm.getDomid(), ('command', 'continue'))
-
-    def recreate(self):
-        self.pid = self.vm.gatherDom(('image/device-model-pid', int))
-
-    def destroy(self, suspend = False):
-        if self.pid and not suspend:
-            try:
-                os.kill(self.pid, signal.SIGKILL)
-            except OSError, exn:
-                log.exception(exn)
-            try:
-                os.waitpid(self.pid, 0)
-            except OSError, exn:
-                # 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.
-                pass
-            self.pid = None
-            state = xstransact.Remove("/local/domain/0/device-model/%i"
-                                      % self.vm.getDomid())
+        return args
+
+    def buildDomain(self):
+        store_evtchn = self.vm.getStorePort()
+
+        mem_mb = self.getRequiredInitialReservation() / 1024
+
+        log.debug("domid          = %d", self.vm.getDomid())
+        log.debug("image          = %s", self.kernel)
+        log.debug("store_evtchn   = %d", store_evtchn)
+        log.debug("memsize        = %d", mem_mb)
+        log.debug("vcpus          = %d", self.vm.getVCpuCount())
+        log.debug("pae            = %d", self.pae)
+        log.debug("acpi           = %d", self.acpi)
+        log.debug("apic           = %d", self.apic)
+
+        rc = xc.hvm_build(domid          = self.vm.getDomid(),
+                          image          = self.kernel,
+                          store_evtchn   = store_evtchn,
+                          memsize        = mem_mb,
+                          vcpus          = self.vm.getVCpuCount(),
+                          pae            = self.pae,
+                          acpi           = self.acpi,
+                          apic           = self.apic)
+        rc['notes'] = { 'SUSPEND_CANCEL': 1 }
+        return rc
 
 
 class IA64_HVM_ImageHandler(HVMImageHandler):
@@ -514,6 +526,13 @@ class IA64_HVM_ImageHandler(HVMImageHand
     def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
         # Explicit shadow memory is not a concept 
         return 0
+
+    def getDeviceModelArgs(self, restore = False):
+        args = HVMImageHandler.getDeviceModelArgs(self, restore)
+        args = args + ([ "-m", "%s" %
+                         (self.getRequiredInitialReservation() / 1024) ])
+        return args
+
 
 class X86_HVM_ImageHandler(HVMImageHandler):
 
diff -r 912986c9283d tools/python/xen/xend/server/vfbif.py
--- a/tools/python/xen/xend/server/vfbif.py     Wed Aug 22 16:17:45 2007 -0400
+++ b/tools/python/xen/xend/server/vfbif.py     Wed Aug 22 16:17:49 2007 -0400
@@ -5,14 +5,6 @@ import xen.xend
 import xen.xend
 import os
 
-def spawn_detached(path, args, env):
-    p = os.fork()
-    if p == 0:
-        os.spawnve(os.P_NOWAIT, path, args, env)
-        os._exit(0)
-    else:
-        os.waitpid(p, 0)
-        
 CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused',
                   'display', 'xauthority', 'keymap',
                   'uuid', 'location', 'protocol']
@@ -43,65 +35,9 @@ class VfbifController(DevController):
                      for i in range(len(CONFIG_ENTRIES))
                      if devinfo[i] is not None])
 
-
-    def createDevice(self, config):
-        DevController.createDevice(self, config)
-        if self.vm.info.is_hvm():
-            # is HVM, so qemu-dm will handle the vfb.
-            return
-        
-        args = [ xen.util.auxbin.pathTo("qemu-dm"),
-                 "-M", "xenpv",
-                 "-d", "%d" % self.vm.getDomid(),
-                 "-domain-name", self.vm.getName() ]
-        t = config.get("type", None)
-        if t == "vnc":
-            passwd = None
-            if config.has_key("vncpasswd"):
-                passwd = config["vncpasswd"]
-            else:
-                passwd = 
xen.xend.XendOptions.instance().get_vncpasswd_default()
-            if passwd:
-                self.vm.storeVm("vncpasswd", passwd)
-                log.debug("Stored a VNC password for vfb access")
-            else:
-                log.debug("No VNC passwd configured for vfb access")
-
-            vnclisten = config.get('vnclisten',
-                                   
xen.xend.XendOptions.instance().get_vnclisten_address())
-            vncdisplay = config.get('vncdisplay', 0)
-            args += ['-vnc', "%s:%d" % (vnclisten, vncdisplay)]
-
-            if config.get('vncunused', 0):
-                args += ['-vncunused']
-
-            if config.has_key("keymap"):
-                args += ["-k", "%s" % config["keymap"]]
-            else:
-                xoptions = xen.xend.XendOptions.instance()
-                if xoptions.get_keymap():
-                    args += ["-k", "%s" % xoptions.get_keymap()]
-
-            spawn_detached(args[0], args, os.environ)
-        elif t == "sdl":
-            env = dict(os.environ)
-            if config.has_key("display"):
-                env['DISPLAY'] = config["display"]
-            if config.has_key("xauthority"):
-                env['XAUTHORITY'] = config["xauthority"]
-            spawn_detached(args[0], args, env)
-        else:
-            raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
-
-
     def waitForDevice(self, devid):
-        if self.vm.info.get('HVM_boot_policy'):
-            log.debug('skip waiting for HVM vfb')
-            # is a qemu-dm managed device, don't wait for hotplug for these.
-            return
-
-        DevController.waitForDevice(self, devid)
-
+        # is a qemu-dm managed device, don't wait for hotplug for these.
+        return
 
     def reconfigureDevice(self, _, config):
         """ Only allow appending location information of vnc port into
@@ -115,20 +51,15 @@ class VfbifController(DevController):
         raise VmError('Refusing to reconfigure device vfb:%d' % devid)
 
     def destroyDevice(self, devid, force):
-        if self.vm.info.get('HVM_boot_policy'):
-            # remove the backend xenstore entries for HVM guests no matter
-            # what
-            DevController.destroyDevice(self, devid, True)
-        else:
-            DevController.destroyDevice(self, devid, force)
-
+        # remove the backend xenstore entries no matter what
+        # because we kill qemu-dm with extreme prejudice
+        # not giving it a chance to remove them itself
+        DevController.destroyDevice(self, devid, True)
 
     def migrate(self, deviceConfig, network, dst, step, domName):
-        if self.vm.info.get('HVM_boot_policy'):        
-            return 0
-        return DevController.migrate(self, deviceConfig, network, dst, step,
-                                     domName)
-    
+        # Handled by qemu-dm so no action needed
+        return 0
+
 class VkbdifController(DevController):
     """Virtual keyboard controller. Handles all vkbd devices for a domain.
     """
@@ -141,22 +72,15 @@ class VkbdifController(DevController):
         return (devid, back, front)
 
     def waitForDevice(self, config):
-        if self.vm.info.get('HVM_boot_policy'):
-            # is a qemu-dm managed device, don't wait for hotplug for these.
-            return
-
-        DevController.waitForDevice(self, config)
+        # is a qemu-dm managed device, don't wait for hotplug for these.
+        return
 
     def destroyDevice(self, devid, force):
-        if self.vm.info.get('HVM_boot_policy'):
-            # remove the backend xenstore entries for HVM guests no matter
-            # what
-            DevController.destroyDevice(self, devid, True)
-        else:
-            DevController.destroyDevice(self, devid, force)
+        # remove the backend xenstore entries no matter what
+        # because we kill qemu-dm with extreme prejudice
+        # not giving it a chance to remove them itself
+        DevController.destroyDevice(self, devid, True)
 
     def migrate(self, deviceConfig, network, dst, step, domName):
-        if self.vm.info.get('HVM_boot_policy'):        
-            return 0
-        return DevController.migrate(self, deviceConfig, network, dst, step,
-                                     domName)        
+        # Handled by qemu-dm so no action needed
+        return 0

-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel