ia64/xen-unstable

changeset 6898:e85f93d1ca59

Update image handling code for xstransact.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Thu Sep 15 16:55:05 2005 +0000 (2005-09-15)
parents c27431cf81f9
children 2f5537317988
files tools/python/xen/xend/XendBootloader.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/python/xen/xm/create.py
line diff
     1.1 --- a/tools/python/xen/xend/XendBootloader.py	Thu Sep 15 13:17:24 2005 +0000
     1.2 +++ b/tools/python/xen/xend/XendBootloader.py	Thu Sep 15 16:55:05 2005 +0000
     1.3 @@ -89,6 +89,4 @@ def bootloader(blexec, disk, quiet = 0, 
     1.4      if vcpus and sxp.child_value(config_image, "vcpus") is None:
     1.5          config_image.append(['vcpus', vcpus])
     1.6  
     1.7 -    config = ['image', config_image]
     1.8 -    return config
     1.9 -
    1.10 +    return config_image
     2.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 15 13:17:24 2005 +0000
     2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Sep 15 16:55:05 2005 +0000
     2.3 @@ -214,7 +214,6 @@ class XendDomainInfo:
     2.4          DBVar('restart_state', ty='str'),
     2.5          DBVar('restart_time',  ty='float'),
     2.6          DBVar('restart_count', ty='int'),
     2.7 -        DBVar('device_model_pid', ty='int'),
     2.8          ]
     2.9      
    2.10      def __init__(self, uuid, path, db):
    2.11 @@ -264,7 +263,6 @@ class XendDomainInfo:
    2.12          
    2.13          self.vcpus = 1
    2.14          self.bootloader = None
    2.15 -        self.device_model_pid = 0
    2.16  
    2.17          self.writeVm("uuid", self.uuid)
    2.18          self.storeDom("vm", self.path)
    2.19 @@ -306,8 +304,6 @@ class XendDomainInfo:
    2.20          self.db.saveDB(save=save, sync=sync)
    2.21  
    2.22      def exportToDB(self, save=False, sync=False):
    2.23 -        if self.image:
    2.24 -            self.image.exportToDB(save=save, sync=sync)
    2.25          self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
    2.26  
    2.27      def importFromDB(self):
    2.28 @@ -589,8 +585,6 @@ class XendDomainInfo:
    2.29              sxpr.append(devs)
    2.30          if self.config:
    2.31              sxpr.append(['config', self.config])
    2.32 -        if self.device_model_pid:
    2.33 -            sxpr.append(['device_model_pid',self.device_model_pid])
    2.34          return sxpr
    2.35  
    2.36      def sxpr_devices(self):
    2.37 @@ -759,7 +753,6 @@ class XendDomainInfo:
    2.38                  pass
    2.39          if self.image:
    2.40              try:
    2.41 -                self.device_model_pid = 0
    2.42                  self.image.destroy()
    2.43                  self.image = None
    2.44              except:
    2.45 @@ -865,8 +858,7 @@ class XendDomainInfo:
    2.46                  ctrl.initController(reboot=True)
    2.47          else:
    2.48              self.create_configured_devices()
    2.49 -        if not self.device_model_pid:
    2.50 -            self.device_model_pid = self.image.createDeviceModel()
    2.51 +        self.image.createDeviceModel()
    2.52  
    2.53      def device_create(self, dev_config):
    2.54          """Create a new device.
     3.1 --- a/tools/python/xen/xend/image.py	Thu Sep 15 13:17:24 2005 +0000
     3.2 +++ b/tools/python/xen/xend/image.py	Thu Sep 15 16:55:05 2005 +0000
     3.3 @@ -36,10 +36,13 @@ SIF_NET_BE_DOMAIN = (1<<5)
     3.4  """Flag for a TPM device backend domain."""
     3.5  SIF_TPM_BE_DOMAIN = (1<<7)
     3.6  
     3.7 +MAX_GUEST_CMDLINE = 1024
     3.8 +
     3.9  class ImageHandler:
    3.10      """Abstract base class for image handlers.
    3.11  
    3.12 -    initDomain() is called to initialise the domain memory.
    3.13 +    initDomain() is called to initialise the domain memory and parse
    3.14 +    the configuration.
    3.15      
    3.16      createImage() is called to configure and build the domain from its
    3.17      kernel image and ramdisk etc.
    3.18 @@ -103,34 +106,42 @@ class ImageHandler:
    3.19      #======================================================================
    3.20      # Instance vars and methods.
    3.21  
    3.22 -    db = None
    3.23      ostype = None
    3.24  
    3.25 -    config = None
    3.26      kernel = None
    3.27      ramdisk = None
    3.28      cmdline = None
    3.29 +
    3.30      flags = 0
    3.31  
    3.32 -    __exports__ = [
    3.33 -        DBVar('ostype',  ty='str'),
    3.34 -        DBVar('config',  ty='sxpr'),
    3.35 -        DBVar('kernel',  ty='str'),
    3.36 -        DBVar('ramdisk', ty='str'),
    3.37 -        DBVar('cmdline', ty='str'),
    3.38 -        DBVar('flags',   ty='int'),
    3.39 -        ]
    3.40 +    def __init__(self, vm, config=None):
    3.41 +        self.vm = vm
    3.42 +        self.configure(config)
    3.43  
    3.44 -    def __init__(self, vm, config):
    3.45 -        self.vm = vm
    3.46 -        self.db = vm.db.addChild('/image')
    3.47 -        self.config = config
    3.48 -
    3.49 -    def exportToDB(self, save=False, sync=False):
    3.50 -        self.db.exportToDB(self, fields=self.__exports__, save=save, sync=sync)
    3.51 -
    3.52 -    def importFromDB(self):
    3.53 -        self.db.importFromDB(self, fields=self.__exports__)
    3.54 +    def configure(self, config):
    3.55 +        """Config actions common to all unix-like domains."""
    3.56 +        if not config:
    3.57 +            self.kernel, self.cmdline, self.ramdisk = self.vm.gatherVm(
    3.58 +                ("image/kernel"), ("image/cmdline"), ("image/ramdisk"))
    3.59 +            return
    3.60 +        
    3.61 +        self.kernel = sxp.child_value(config, "kernel")
    3.62 +        self.cmdline = ""
    3.63 +        ip = sxp.child_value(config, "ip", None)
    3.64 +        if ip:
    3.65 +            self.cmdline += " ip=" + ip
    3.66 +        root = sxp.child_value(config, "root")
    3.67 +        if root:
    3.68 +            self.cmdline += " root=" + root
    3.69 +        args = sxp.child_value(config, "args")
    3.70 +        if args:
    3.71 +            self.cmdline += " " + args
    3.72 +        self.ramdisk = sxp.child_value(config, "ramdisk", '')
    3.73 +        
    3.74 +        self.vm.storeVm(("image/ostype", self.ostype),
    3.75 +                        ("image/kernel", self.kernel),
    3.76 +                        ("image/cmdline", self.cmdline),
    3.77 +                        ("image/ramdisk", self.ramdisk))
    3.78  
    3.79      def unlink(self, f):
    3.80          if not f: return
    3.81 @@ -159,12 +170,7 @@ class ImageHandler:
    3.82          xc.domain_setmaxmem(dom, mem_kb)
    3.83  
    3.84          try:
    3.85 -            # Give the domain some memory below 4GB
    3.86 -            lmem_kb = 0
    3.87 -            if lmem_kb > 0:
    3.88 -                xc.domain_memory_increase_reservation(dom, min(lmem_kb,mem_kb), 0, 32)
    3.89 -            if mem_kb > lmem_kb:
    3.90 -                xc.domain_memory_increase_reservation(dom, mem_kb-lmem_kb, 0, 0)
    3.91 +            xc.domain_memory_increase_reservation(dom, mem_kb, 0, 0)
    3.92          except:
    3.93              xc.domain_destroy(dom)
    3.94              raise
    3.95 @@ -177,48 +183,33 @@ class ImageHandler:
    3.96          """Entry point to create domain memory image.
    3.97          Override in subclass  if needed.
    3.98          """
    3.99 -        self.configure()
   3.100          self.createDomain()
   3.101  
   3.102 -    def configure(self):
   3.103 -        """Config actions common to all unix-like domains."""
   3.104 -        self.kernel = sxp.child_value(self.config, "kernel")
   3.105 -        self.cmdline = ""
   3.106 -        ip = sxp.child_value(self.config, "ip", None)
   3.107 -        if ip:
   3.108 -            self.cmdline += " ip=" + ip
   3.109 -        root = sxp.child_value(self.config, "root")
   3.110 -        if root:
   3.111 -            self.cmdline += " root=" + root
   3.112 -        args = sxp.child_value(self.config, "args")
   3.113 -        if args:
   3.114 -            self.cmdline += " " + args
   3.115 -        self.ramdisk = sxp.child_value(self.config, "ramdisk", '')
   3.116 -        
   3.117      def createDomain(self):
   3.118          """Build the domain boot image.
   3.119          """
   3.120 +        if self.vm.recreate or self.vm.restore:
   3.121 +            return
   3.122 +
   3.123          # Set params and call buildDomain().
   3.124          self.flags = 0
   3.125          if self.vm.netif_backend: self.flags |= SIF_NET_BE_DOMAIN
   3.126          if self.vm.blkif_backend: self.flags |= SIF_BLK_BE_DOMAIN
   3.127          if self.vm.tpmif_backend: self.flags |= SIF_TPM_BE_DOMAIN
   3.128  
   3.129 -        if self.vm.recreate or self.vm.restore:
   3.130 -            return
   3.131          if not os.path.isfile(self.kernel):
   3.132              raise VmError('Kernel image does not exist: %s' % self.kernel)
   3.133          if self.ramdisk and not os.path.isfile(self.ramdisk):
   3.134              raise VmError('Kernel ramdisk does not exist: %s' % self.ramdisk)
   3.135 -        if len(self.cmdline) >= 256:
   3.136 -            log.warning('kernel cmdline too long, domain %d', self.vm.getDomain())
   3.137 +        if len(self.cmdline) >= MAX_GUEST_CMDLINE:
   3.138 +            log.warning('kernel cmdline too long, domain %d', self.vm.domid)
   3.139          
   3.140          log.info("buildDomain os=%s dom=%d vcpus=%d", self.ostype,
   3.141 -                 self.vm.getDomain(), self.vm.vcpus)
   3.142 +                 self.vm.domid, self.vm.vcpus)
   3.143          err = self.buildDomain()
   3.144          if err != 0:
   3.145              raise VmError('Building domain failed: ostype=%s dom=%d err=%d'
   3.146 -                          % (self.ostype, self.vm.getDomain(), err))
   3.147 +                          % (self.ostype, self.vm.domid, err))
   3.148  
   3.149      def getDomainMemory(self, mem_mb):
   3.150          """Memory (in KB) the domain will need for mem_mb (in MB)."""
   3.151 @@ -258,7 +249,7 @@ class LinuxImageHandler(ImageHandler):
   3.152          else:
   3.153              console_evtchn = 0
   3.154  
   3.155 -        log.debug("dom            = %d", self.vm.getDomain())
   3.156 +        log.debug("dom            = %d", self.vm.domid)
   3.157          log.debug("image          = %s", self.kernel)
   3.158          log.debug("store_evtchn   = %d", store_evtchn)
   3.159          log.debug("console_evtchn = %d", console_evtchn)
   3.160 @@ -267,7 +258,7 @@ class LinuxImageHandler(ImageHandler):
   3.161          log.debug("flags          = %d", self.flags)
   3.162          log.debug("vcpus          = %d", self.vm.vcpus)
   3.163  
   3.164 -        ret = xc.linux_build(dom            = self.vm.getDomain(),
   3.165 +        ret = xc.linux_build(dom            = self.vm.domid,
   3.166                               image          = self.kernel,
   3.167                               store_evtchn   = store_evtchn,
   3.168                               console_evtchn = console_evtchn,
   3.169 @@ -282,49 +273,63 @@ class LinuxImageHandler(ImageHandler):
   3.170  
   3.171  class VmxImageHandler(ImageHandler):
   3.172  
   3.173 -    __exports__ = ImageHandler.__exports__ + [
   3.174 -        DBVar('memmap',        ty='str'),
   3.175 -        DBVar('memmap_value',  ty='sxpr'),
   3.176 -        # device channel?
   3.177 -        ]
   3.178 -    
   3.179      ostype = "vmx"
   3.180 +
   3.181      memmap = None
   3.182      memmap_value = []
   3.183      device_channel = None
   3.184      pid = 0
   3.185 +
   3.186 +    def configure(self, config):
   3.187 +        ImageHandler.configure(self, config)
   3.188 +        if not config:
   3.189 +            self.memmap, self.dmargs, self.device_model, self.display = self.vm.gatherVm(
   3.190 +                ("image/memmap"), ("image/dmargs"), ("image/device-model"),
   3.191 +                ("image/display"))
   3.192 +            return
   3.193 +        
   3.194 +        self.memmap = sxp.child_value(config, 'memmap')
   3.195 +        self.dmargs = self.parseDeviceModelArgs(config)
   3.196 +        self.device_model = sxp.child_value(config, 'device_model')
   3.197 +        if not self.device_model:
   3.198 +            raise VmError("vmx: missing device model")
   3.199 +        self.display = sxp.child_value(config, 'display')
   3.200 +
   3.201 +        self.storeVm(("image/memmap", self.memmap),
   3.202 +                     ("image/dmargs", self.dmargs),
   3.203 +                     ("image/device-model", self.device_model),
   3.204 +                     ("image/display", self.display))
   3.205 +
   3.206      def createImage(self):
   3.207          """Create a VM for the VMX environment.
   3.208          """
   3.209 -        self.configure()
   3.210          self.parseMemmap()
   3.211          self.createDomain()
   3.212  
   3.213      def buildDomain(self):
   3.214          # Create an event channel
   3.215 -        self.device_channel = channel.eventChannel(0, self.vm.getDomain())
   3.216 +        self.device_channel = channel.eventChannel(0, self.vm.domid)
   3.217          log.info("VMX device model port: %d", self.device_channel.port2)
   3.218          if self.vm.store_channel:
   3.219              store_evtchn = self.vm.store_channel.port2
   3.220          else:
   3.221              store_evtchn = 0
   3.222 -        ret = xc.vmx_build(dom            = self.vm.getDomain(),
   3.223 -                            image          = self.kernel,
   3.224 -                            control_evtchn = self.device_channel.port2,
   3.225 -                            store_evtchn   = store_evtchn,
   3.226 -                            memsize        = self.vm.memory,
   3.227 -                            memmap         = self.memmap_value,
   3.228 -                            cmdline        = self.cmdline,
   3.229 -                            ramdisk        = self.ramdisk,
   3.230 -                            flags          = self.flags,
   3.231 -                            vcpus          = self.vm.vcpus)
   3.232 +        ret = xc.vmx_build(dom            = self.vm.domid,
   3.233 +                           image          = self.kernel,
   3.234 +                           control_evtchn = self.device_channel.port2,
   3.235 +                           store_evtchn   = store_evtchn,
   3.236 +                           memsize        = self.vm.memory,
   3.237 +                           memmap         = self.memmap_value,
   3.238 +                           cmdline        = self.cmdline,
   3.239 +                           ramdisk        = self.ramdisk,
   3.240 +                           flags          = self.flags,
   3.241 +                           vcpus          = self.vm.vcpus)
   3.242          if isinstance(ret, dict):
   3.243              self.set_vminfo(ret)
   3.244              return 0
   3.245          return ret
   3.246  
   3.247      def parseMemmap(self):
   3.248 -        self.memmap = sxp.child_value(self.vm.config, "memmap")
   3.249          if self.memmap is None:
   3.250              return
   3.251          memmap = sxp.parse(open(self.memmap))[0]
   3.252 @@ -333,12 +338,12 @@ class VmxImageHandler(ImageHandler):
   3.253          
   3.254      # Return a list of cmd line args to the device models based on the
   3.255      # xm config file
   3.256 -    def parseDeviceModelArgs(self):
   3.257 -	dmargs = [ 'cdrom', 'boot', 'fda', 'fdb',
   3.258 +    def parseDeviceModelArgs(self, config):
   3.259 +        dmargs = [ 'cdrom', 'boot', 'fda', 'fdb',
   3.260                     'localtime', 'serial', 'stdvga', 'isa' ] 
   3.261 -	ret = []
   3.262 -	for a in dmargs:
   3.263 -       	    v = sxp.child_value(self.vm.config, a)
   3.264 +        ret = []
   3.265 +        for a in dmargs:
   3.266 +            v = sxp.child_value(config, a)
   3.267  
   3.268              # python doesn't allow '-' in variable names
   3.269              if a == 'stdvga': a = 'std-vga'
   3.270 @@ -347,13 +352,13 @@ class VmxImageHandler(ImageHandler):
   3.271              if a in ['localtime', 'std-vga', 'isa']:
   3.272                  if v != None: v = int(v)
   3.273  
   3.274 -	    log.debug("args: %s, val: %s" % (a,v))
   3.275 -	    if v: 
   3.276 -		ret.append("-%s" % a)
   3.277 -		ret.append("%s" % v)
   3.278 +            log.debug("args: %s, val: %s" % (a,v))
   3.279 +            if v: 
   3.280 +                ret.append("-%s" % a)
   3.281 +                ret.append("%s" % v)
   3.282  
   3.283          # Handle disk/network related options
   3.284 -        devices = sxp.children(self.vm.config, 'device')
   3.285 +        devices = sxp.children(config, 'device')
   3.286          for device in devices:
   3.287              name = sxp.name(sxp.child0(device))
   3.288              if name == 'vbd':
   3.289 @@ -384,51 +389,48 @@ class VmxImageHandler(ImageHandler):
   3.290                 ret.append("-instance")
   3.291                 ret.append("%s" % instance)
   3.292  
   3.293 -	# Handle graphics library related options
   3.294 -	vnc = sxp.child_value(self.vm.config, 'vnc')
   3.295 -	sdl = sxp.child_value(self.vm.config, 'sdl')
   3.296 -	nographic = sxp.child_value(self.vm.config, 'nographic')
   3.297 -	if nographic:
   3.298 -	    ret.append('-nographic')
   3.299 -	    return ret
   3.300 -	
   3.301 -	if vnc and sdl:
   3.302 -	    ret = ret + ['-vnc-and-sdl', '-k', 'en-us']
   3.303 -	elif vnc:
   3.304 -	    ret = ret + ['-vnc', '-k', 'en-us']
   3.305 -	if vnc:
   3.306 -	    vncport = int(self.vm.getDomain()) + 5900
   3.307 -	    ret = ret + ['-vncport', '%d' % vncport]
   3.308 -	return ret
   3.309 -	      	  
   3.310 +        # Handle graphics library related options
   3.311 +        vnc = sxp.child_value(config, 'vnc')
   3.312 +        sdl = sxp.child_value(config, 'sdl')
   3.313 +        nographic = sxp.child_value(config, 'nographic')
   3.314 +        if nographic:
   3.315 +            ret.append('-nographic')
   3.316 +            return ret
   3.317 +
   3.318 +        if vnc and sdl:
   3.319 +            ret = ret + ['-vnc-and-sdl', '-k', 'en-us']
   3.320 +        elif vnc:
   3.321 +            ret = ret + ['-vnc', '-k', 'en-us']
   3.322 +        if vnc:
   3.323 +            vncport = int(self.vm.domid) + 5900
   3.324 +            ret = ret + ['-vncport', '%d' % vncport]
   3.325 +        return ret
   3.326 +
   3.327      def createDeviceModel(self):
   3.328 -        device_model = sxp.child_value(self.vm.config, 'device_model')
   3.329 -        if not device_model:
   3.330 -            raise VmError("vmx: missing device model")
   3.331 +        if self.pid:
   3.332 +            return
   3.333          # Execute device model.
   3.334          #todo: Error handling
   3.335          # XXX RN: note that the order of args matter!
   3.336 -        args = [device_model]
   3.337 +        args = [self.device_model]
   3.338          vnc = self.vncParams()
   3.339          if len(vnc):
   3.340              args = args + vnc
   3.341 -        args = args + ([ "-d",  "%d" % self.vm.getDomain(),
   3.342 +        args = args + ([ "-d",  "%d" % self.vm.domid,
   3.343                    "-p", "%d" % self.device_channel.port1,
   3.344                    "-m", "%s" % self.vm.memory ])
   3.345 -	args = args + self.parseDeviceModelArgs()
   3.346 +        args = args + self.dmargs
   3.347          env = dict(os.environ)
   3.348 -        env['DISPLAY'] = sxp.child_value(self.vm.config, 'display')
   3.349 -        log.info("spawning device models: %s %s", device_model, args)
   3.350 -        self.pid = os.spawnve(os.P_NOWAIT, device_model, args, env)
   3.351 +        env['DISPLAY'] = self.display
   3.352 +        log.info("spawning device models: %s %s", self.device_model, args)
   3.353 +        self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
   3.354          log.info("device model pid: %d", self.pid)
   3.355 -        return self.pid
   3.356  
   3.357      def vncParams(self):
   3.358          # see if a vncviewer was specified
   3.359          # XXX RN: bit of a hack. should unify this, maybe stick in config space
   3.360          vncconnect=[]
   3.361 -        image = self.config
   3.362 -        args = sxp.child_value(image, "args")
   3.363 +        args = self.cmdline
   3.364          if args:
   3.365              arg_list = string.split(args)
   3.366              for arg in arg_list:
   3.367 @@ -442,7 +444,7 @@ class VmxImageHandler(ImageHandler):
   3.368          channel.eventChannelClose(self.device_channel)
   3.369          import signal
   3.370          if not self.pid:
   3.371 -            self.pid = self.vm.device_model_pid
   3.372 +            return
   3.373          os.kill(self.pid, signal.SIGKILL)
   3.374          (pid, status) = os.waitpid(self.pid, 0)
   3.375          self.pid = 0
   3.376 @@ -462,8 +464,9 @@ class VmxImageHandler(ImageHandler):
   3.377          # 1 page for the PGD + 1 pte page for 4MB of memory (rounded)
   3.378          if os.uname()[4] == 'x86_64':
   3.379              return (5 + ((mem_mb + 1) >> 1)) * 4
   3.380 -	elif os.uname()[4] == 'ia64':
   3.381 -	    # XEN/IA64 has p2m table allocated on demand, so only return guest firmware size here.
   3.382 -	    return 16 * 1024
   3.383 +        elif os.uname()[4] == 'ia64':
   3.384 +            # XEN/IA64 has p2m table allocated on demand, so only return
   3.385 +            # guest firmware size here.
   3.386 +            return 16 * 1024
   3.387          else:
   3.388              return (1 + ((mem_mb + 3) >> 2)) * 4
     4.1 --- a/tools/python/xen/xm/create.py	Thu Sep 15 13:17:24 2005 +0000
     4.2 +++ b/tools/python/xen/xm/create.py	Thu Sep 15 16:55:05 2005 +0000
     4.3 @@ -109,7 +109,7 @@ gopts.var('vncviewer', val='no|yes',
     4.4            The address of the vncviewer is passed to the domain on the kernel command
     4.5            line using 'VNC_SERVER=<host>:<port>'. The port used by vnc is 5500 + DISPLAY.
     4.6            A display value with a free port is chosen if possible.
     4.7 -	  Only valid when vnc=1.
     4.8 +          Only valid when vnc=1.
     4.9            """)
    4.10  
    4.11  gopts.var('name', val='NAME',
    4.12 @@ -342,7 +342,7 @@ def strip(pre, s):
    4.13      else:
    4.14          return s
    4.15  
    4.16 -def configure_image(opts, config, vals):
    4.17 +def configure_image(opts, vals):
    4.18      """Create the image config.
    4.19      """
    4.20      config_image = [ vals.builder ]
    4.21 @@ -359,8 +359,7 @@ def configure_image(opts, config, vals):
    4.22          config_image.append(['args', vals.extra])
    4.23      if vals.vcpus:
    4.24          config_image.append(['vcpus', vals.vcpus])
    4.25 -    config.append(['image', config_image ])
    4.26 -
    4.27 +    return config_image
    4.28      
    4.29  def configure_disks(opts, config_devs, vals):
    4.30      """Create the config for disks (virtual block devices).
    4.31 @@ -494,17 +493,17 @@ def configure_vfr(opts, config, vals):
    4.32           config_vfr.append(['vif', ['id', idx], ['ip', ip]])
    4.33       config.append(config_vfr)
    4.34  
    4.35 -def configure_vmx(opts, config_devs, vals):
    4.36 +def configure_vmx(opts, config_image, vals):
    4.37      """Create the config for VMX devices.
    4.38      """
    4.39      args = [ 'memmap', 'device_model', 'cdrom',
    4.40 - 	     'boot', 'fda', 'fdb', 'localtime', 'serial', 'macaddr', 'stdvga', 
    4.41 -             'isa', 'nographic', 'vnc', 'vncviewer', 'sdl', 'display']	  
    4.42 +             'boot', 'fda', 'fdb', 'localtime', 'serial', 'macaddr', 'stdvga', 
    4.43 +             'isa', 'nographic', 'vnc', 'vncviewer', 'sdl', 'display']
    4.44      for a in args:
    4.45 -	if (vals.__dict__[a]):
    4.46 -    	    config_devs.append([a, vals.__dict__[a]])
    4.47 +        if (vals.__dict__[a]):
    4.48 +            config_image.append([a, vals.__dict__[a]])
    4.49  
    4.50 -def run_bootloader(opts, config, vals):
    4.51 +def run_bootloader(opts, vals):
    4.52      if not os.access(vals.bootloader, os.X_OK):
    4.53          opts.err("Bootloader isn't executable")
    4.54      if len(vals.disk) < 1:
    4.55 @@ -512,11 +511,8 @@ def run_bootloader(opts, config, vals):
    4.56      (uname, dev, mode, backend) = vals.disk[0]
    4.57      file = blkif.blkdev_uname_to_file(uname)
    4.58  
    4.59 -    blcfg = bootloader(vals.bootloader, file, not vals.console_autoconnect,
    4.60 -                       vals.vcpus, vals.blentry)
    4.61 -
    4.62 -    config.append(['bootloader', vals.bootloader])
    4.63 -    config.append(blcfg)
    4.64 +    return bootloader(vals.bootloader, file, not vals.console_autoconnect,
    4.65 +                      vals.vcpus, vals.blentry)
    4.66  
    4.67  def make_config(opts, vals):
    4.68      """Create the domain configuration.
    4.69 @@ -542,16 +538,19 @@ def make_config(opts, vals):
    4.70          config.append(['restart', vals.restart])
    4.71  
    4.72      if vals.bootloader:
    4.73 -        run_bootloader(opts, config, vals)
    4.74 +        config.append(['bootloader', vals.bootloader])
    4.75 +        config_image = run_bootloader(opts, vals)
    4.76      else:
    4.77 -        configure_image(opts, config, vals)
    4.78 +        config_image = configure_image(opts, vals)
    4.79 +    configure_vmx(opts, config_image, vals)
    4.80 +    config.append(['image', config_image ])
    4.81 +
    4.82      config_devs = []
    4.83      configure_disks(opts, config_devs, vals)
    4.84      configure_pci(opts, config_devs, vals)
    4.85      configure_vifs(opts, config_devs, vals)
    4.86      configure_usb(opts, config_devs, vals)
    4.87      configure_vtpm(opts, config_devs, vals)
    4.88 -    configure_vmx(opts, config_devs, vals)
    4.89      config += config_devs
    4.90  
    4.91      return config