ia64/xen-unstable
changeset 11340:24258e322e88
[XEND] abstract architecture-specific bits in image.py
- create arch.type (which evaluates to "x86", "ia64" or "powerpc")
- create subclasses for x86 and ia64 HVM loaders
- rework findImageHandlerClass()
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
- create arch.type (which evaluates to "x86", "ia64" or "powerpc")
- create subclasses for x86 and ia64 HVM loaders
- rework findImageHandlerClass()
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author | Ewan Mellor <ewan@xensource.com> |
---|---|
date | Tue Aug 29 23:20:22 2006 +0100 (2006-08-29) |
parents | 051dc0911547 |
children | 90fb2c4d33a5 |
files | tools/python/xen/xend/FlatDeviceTree.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/arch.py tools/python/xen/xend/image.py |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/python/xen/xend/FlatDeviceTree.py Tue Aug 29 23:20:22 2006 +0100 1.3 @@ -0,0 +1,323 @@ 1.4 +#!/usr/bin/env python 1.5 +# 1.6 +# This library is free software; you can redistribute it and/or 1.7 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 1.8 +# License as published by the Free Software Foundation. 1.9 +# 1.10 +# This library is distributed in the hope that it will be useful, 1.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 1.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.13 +# Lesser General Public License for more details. 1.14 +# 1.15 +# You should have received a copy of the GNU Lesser General Public 1.16 +# License along with this library; if not, write to the Free Software 1.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1.18 +# 1.19 +# Copyright (C) IBM Corp. 2006 1.20 +# 1.21 +# Authors: Hollis Blanchard <hollisb@us.ibm.com> 1.22 + 1.23 +import os 1.24 +import sys 1.25 +import struct 1.26 +import stat 1.27 +import re 1.28 + 1.29 +_OF_DT_HEADER = int("d00dfeed", 16) # avoid signed/unsigned FutureWarning 1.30 +_OF_DT_BEGIN_NODE = 0x1 1.31 +_OF_DT_END_NODE = 0x2 1.32 +_OF_DT_PROP = 0x3 1.33 +_OF_DT_END = 0x9 1.34 + 1.35 +def _bincat(seq, separator=''): 1.36 + '''Concatenate the contents of seq into a bytestream.''' 1.37 + strs = [] 1.38 + for item in seq: 1.39 + if type(item) == type(0): 1.40 + strs.append(struct.pack(">I", item)) 1.41 + else: 1.42 + try: 1.43 + strs.append(item.to_bin()) 1.44 + except AttributeError, e: 1.45 + strs.append(item) 1.46 + return separator.join(strs) 1.47 + 1.48 +def _alignup(val, alignment): 1.49 + return (val + alignment - 1) & ~(alignment - 1) 1.50 + 1.51 +def _pad(buf, alignment): 1.52 + '''Pad bytestream with NULLs to specified alignment.''' 1.53 + padlen = _alignup(len(buf), alignment) 1.54 + return buf + '\0' * (padlen - len(buf)) 1.55 + # not present in Python 2.3: 1.56 + #return buf.ljust(_padlen, '\0') 1.57 + 1.58 +def _indent(item): 1.59 + indented = [] 1.60 + for line in str(item).splitlines(True): 1.61 + indented.append(' ' + line) 1.62 + return ''.join(indented) 1.63 + 1.64 +class _Property: 1.65 + _nonprint = re.compile('[\000-\037\200-\377]') 1.66 + def __init__(self, node, name, value): 1.67 + self.node = node 1.68 + self.value = value 1.69 + self.name = name 1.70 + self.node.tree.stradd(name) 1.71 + 1.72 + def __str__(self): 1.73 + result = self.name 1.74 + if self.value: 1.75 + searchtext = self.value 1.76 + # it's ok for a string to end in NULL 1.77 + if searchtext.find('\000') == len(searchtext)-1: 1.78 + searchtext = searchtext[:-1] 1.79 + m = self._nonprint.search(searchtext) 1.80 + if m: 1.81 + bytes = struct.unpack("B" * len(self.value), self.value) 1.82 + hexbytes = [ '%02x' % b for b in bytes ] 1.83 + words = [] 1.84 + for i in range(0, len(self.value), 4): 1.85 + words.append(''.join(hexbytes[i:i+4])) 1.86 + v = '<' + ' '.join(words) + '>' 1.87 + else: 1.88 + v = '"%s"' % self.value 1.89 + result += ': ' + v 1.90 + return result 1.91 + 1.92 + def to_bin(self): 1.93 + offset = self.node.tree.stroffset(self.name) 1.94 + return struct.pack('>III', _OF_DT_PROP, len(self.value), offset) \ 1.95 + + _pad(self.value, 4) 1.96 + 1.97 +class _Node: 1.98 + def __init__(self, tree, name): 1.99 + self.tree = tree 1.100 + self.name = name 1.101 + self.props = {} 1.102 + self.children = {} 1.103 + self.phandle = 0 1.104 + 1.105 + def __str__(self): 1.106 + propstrs = [ _indent(prop) for prop in self.props.values() ] 1.107 + childstrs = [ _indent(child) for child in self.children.values() ] 1.108 + return '%s:\n%s\n%s' % (self.name, '\n'.join(propstrs), 1.109 + '\n'.join(childstrs)) 1.110 + 1.111 + def to_bin(self): 1.112 + name = _pad(self.name + '\0', 4) 1.113 + return struct.pack('>I', _OF_DT_BEGIN_NODE) + \ 1.114 + name + \ 1.115 + _bincat(self.props.values()) + \ 1.116 + _bincat(self.children.values()) + \ 1.117 + struct.pack('>I', _OF_DT_END_NODE) 1.118 + 1.119 + def addprop(self, propname, *cells): 1.120 + '''setprop with duplicate error-checking.''' 1.121 + if propname in self.props: 1.122 + raise AttributeError('%s/%s already exists' % (self.name, propname)) 1.123 + self.setprop(propname, *cells) 1.124 + 1.125 + def setprop(self, propname, *cells): 1.126 + self.props[propname] = _Property(self, propname, _bincat(cells)) 1.127 + 1.128 + def addnode(self, nodename): 1.129 + '''newnode with duplicate error-checking.''' 1.130 + if nodename in self.children: 1.131 + raise AttributeError('%s/%s already exists' % (self.name, nodename)) 1.132 + return self.newnode(nodename) 1.133 + 1.134 + def newnode(self, nodename): 1.135 + node = _Node(self.tree, nodename) 1.136 + self.children[nodename] = node 1.137 + return node 1.138 + 1.139 + def getprop(self, propname): 1.140 + return self.props[propname] 1.141 + 1.142 + def getchild(self, nodename): 1.143 + return self.children[nodename] 1.144 + 1.145 + def get_phandle(self): 1.146 + if self.phandle: 1.147 + return self.phandle 1.148 + self.phandle = self.tree.alloc_phandle() 1.149 + self.addprop('linux,phandle', self.phandle) 1.150 + return self.phandle 1.151 + 1.152 +class _Header: 1.153 + def __init__(self): 1.154 + self.magic = 0 1.155 + self.totalsize = 0 1.156 + self.off_dt_struct = 0 1.157 + self.off_dt_strings = 0 1.158 + self.off_mem_rsvmap = 0 1.159 + self.version = 0 1.160 + self.last_comp_version = 0 1.161 + self.boot_cpuid_phys = 0 1.162 + self.size_dt_strings = 0 1.163 + def to_bin(self): 1.164 + return struct.pack('>9I', 1.165 + self.magic, 1.166 + self.totalsize, 1.167 + self.off_dt_struct, 1.168 + self.off_dt_strings, 1.169 + self.off_mem_rsvmap, 1.170 + self.version, 1.171 + self.last_comp_version, 1.172 + self.boot_cpuid_phys, 1.173 + self.size_dt_strings) 1.174 + 1.175 +class _StringBlock: 1.176 + def __init__(self): 1.177 + self.table = [] 1.178 + def to_bin(self): 1.179 + return _bincat(self.table, '\0') + '\0' 1.180 + def add(self, str): 1.181 + self.table.append(str) 1.182 + def getoffset(self, str): 1.183 + return self.to_bin().index(str + '\0') 1.184 + 1.185 +class Tree(_Node): 1.186 + def __init__(self): 1.187 + self.last_phandle = 0 1.188 + self.strings = _StringBlock() 1.189 + self.reserved = [(0, 0)] 1.190 + _Node.__init__(self, self, '\0') 1.191 + 1.192 + def alloc_phandle(self): 1.193 + self.last_phandle += 1 1.194 + return self.last_phandle 1.195 + 1.196 + def stradd(self, str): 1.197 + return self.strings.add(str) 1.198 + 1.199 + def stroffset(self, str): 1.200 + return self.strings.getoffset(str) 1.201 + 1.202 + def reserve(self, start, len): 1.203 + self.reserved.insert(0, (start, len)) 1.204 + 1.205 + def to_bin(self): 1.206 + # layout: 1.207 + # header 1.208 + # reservation map 1.209 + # string block 1.210 + # data block 1.211 + 1.212 + datablock = _Node.to_bin(self) 1.213 + 1.214 + r = [ struct.pack('>QQ', rsrv[0], rsrv[1]) for rsrv in self.reserved ] 1.215 + reserved = _bincat(r) 1.216 + 1.217 + strblock = _pad(self.strings.to_bin(), 4) 1.218 + strblocklen = len(strblock) 1.219 + 1.220 + header = _Header() 1.221 + header.magic = _OF_DT_HEADER 1.222 + header.off_mem_rsvmap = _alignup(len(header.to_bin()), 8) 1.223 + header.off_dt_strings = header.off_mem_rsvmap + len(reserved) 1.224 + header.off_dt_struct = header.off_dt_strings + strblocklen 1.225 + header.version = 0x10 1.226 + header.last_comp_version = 0x10 1.227 + header.boot_cpuid_phys = 0 1.228 + header.size_dt_strings = strblocklen 1.229 + 1.230 + payload = reserved + \ 1.231 + strblock + \ 1.232 + datablock + \ 1.233 + struct.pack('>I', _OF_DT_END) 1.234 + header.totalsize = len(payload) + _alignup(len(header.to_bin()), 8) 1.235 + return _pad(header.to_bin(), 8) + payload 1.236 + 1.237 +_host_devtree_root = '/proc/device-tree' 1.238 +def _getprop(propname): 1.239 + '''Extract a property from the system's device tree.''' 1.240 + f = file(os.path.join(_host_devtree_root, propname), 'r') 1.241 + data = f.read() 1.242 + f.close() 1.243 + return data 1.244 + 1.245 +def _copynode(node, dirpath, propfilter): 1.246 + '''Extract all properties from a node in the system's device tree.''' 1.247 + dirents = os.listdir(dirpath) 1.248 + for dirent in dirents: 1.249 + fullpath = os.path.join(dirpath, dirent) 1.250 + st = os.lstat(fullpath) 1.251 + if stat.S_ISDIR(st.st_mode): 1.252 + child = node.addnode(dirent) 1.253 + _copytree(child, fullpath, propfilter) 1.254 + elif stat.S_ISREG(st.st_mode) and propfilter(fullpath): 1.255 + node.addprop(dirent, _getprop(fullpath)) 1.256 + 1.257 +def _copytree(node, dirpath, propfilter): 1.258 + path = os.path.join(_host_devtree_root, dirpath) 1.259 + _copynode(node, path, propfilter) 1.260 + 1.261 +def build(imghandler): 1.262 + '''Construct a device tree by combining the domain's configuration and 1.263 + the host's device tree.''' 1.264 + root = Tree() 1.265 + 1.266 + # 4 pages: start_info, console, store, shared_info 1.267 + root.reserve(0x3ffc000, 0x4000) 1.268 + 1.269 + root.addprop('device_type', 'chrp-but-not-really\0') 1.270 + root.addprop('#size-cells', 2) 1.271 + root.addprop('#address-cells', 2) 1.272 + root.addprop('model', 'Momentum,Maple-D\0') 1.273 + root.addprop('compatible', 'Momentum,Maple\0') 1.274 + 1.275 + xen = root.addnode('xen') 1.276 + xen.addprop('start-info', 0, 0x3ffc000, 0, 0x1000) 1.277 + xen.addprop('version', 'Xen-3.0-unstable\0') 1.278 + xen.addprop('reg', 0, imghandler.vm.domid, 0, 0) 1.279 + xen.addprop('domain-name', imghandler.vm.getName() + '\0') 1.280 + xencons = xen.addnode('console') 1.281 + xencons.addprop('interrupts', 1, 0) 1.282 + 1.283 + # XXX split out RMA node 1.284 + mem = root.addnode('memory@0') 1.285 + totalmem = imghandler.vm.getMemoryTarget() * 1024 1.286 + mem.addprop('reg', 0, 0, 0, totalmem) 1.287 + mem.addprop('device_type', 'memory\0') 1.288 + 1.289 + cpus = root.addnode('cpus') 1.290 + cpus.addprop('smp-enabled') 1.291 + cpus.addprop('#size-cells', 0) 1.292 + cpus.addprop('#address-cells', 1) 1.293 + 1.294 + # Copy all properties the system firmware gave us, except for 'linux,' 1.295 + # properties, from 'cpus/@0', once for every vcpu. Hopefully all cpus are 1.296 + # identical... 1.297 + cpu0 = None 1.298 + def _nolinuxprops(fullpath): 1.299 + return not os.path.basename(fullpath).startswith('linux,') 1.300 + for i in range(imghandler.vm.getVCpuCount()): 1.301 + cpu = cpus.addnode('PowerPC,970@0') 1.302 + _copytree(cpu, 'cpus/PowerPC,970@0', _nolinuxprops) 1.303 + # and then overwrite what we need to 1.304 + pft_size = imghandler.vm.info.get('pft-size', 0x14) 1.305 + cpu.setprop('ibm,pft-size', 0, pft_size) 1.306 + 1.307 + # set default CPU 1.308 + if cpu0 == None: 1.309 + cpu0 = cpu 1.310 + 1.311 + chosen = root.addnode('chosen') 1.312 + chosen.addprop('cpu', cpu0.get_phandle()) 1.313 + chosen.addprop('memory', mem.get_phandle()) 1.314 + chosen.addprop('linux,stdout-path', '/xen/console\0') 1.315 + chosen.addprop('interrupt-controller', xen.get_phandle()) 1.316 + chosen.addprop('bootargs', imghandler.cmdline + '\0') 1.317 + # xc_linux_load.c will overwrite these 64-bit properties later 1.318 + chosen.addprop('linux,initrd-start', 0, 0) 1.319 + chosen.addprop('linux,initrd-end', 0, 0) 1.320 + 1.321 + if 1: 1.322 + f = file('/tmp/domU.dtb', 'w') 1.323 + f.write(root.to_bin()) 1.324 + f.close() 1.325 + 1.326 + return root
2.1 --- a/tools/python/xen/xend/XendDomainInfo.py Tue Aug 29 22:51:06 2006 +0100 2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Aug 29 23:20:22 2006 +0100 2.3 @@ -30,7 +30,6 @@ import string 2.4 import time 2.5 import threading 2.6 import os 2.7 -import math 2.8 2.9 import xen.lowlevel.xc 2.10 from xen.util import asserts 2.11 @@ -1286,34 +1285,27 @@ class XendDomainInfo: 2.12 for v in range(0, self.info['max_vcpu_id']+1): 2.13 xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) 2.14 2.15 - # set domain maxmem in KiB 2.16 - xc.domain_setmaxmem(self.domid, self.info['maxmem'] * 1024) 2.17 + # set memory limit 2.18 + maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024) 2.19 + xc.domain_setmaxmem(self.domid, maxmem) 2.20 2.21 - m = self.image.getDomainMemory(self.info['memory'] * 1024) 2.22 + mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024) 2.23 2.24 # get the domain's shadow memory requirement 2.25 - sm = int(math.ceil(self.image.getDomainShadowMemory(m) / 1024.0)) 2.26 - if self.info['shadow_memory'] > sm: 2.27 - sm = self.info['shadow_memory'] 2.28 + shadow_kb = self.image.getRequiredShadowMemory(mem_kb) 2.29 + shadow_kb_req = self.info['shadow_memory'] * 1024 2.30 + if shadow_kb_req > shadow_kb: 2.31 + shadow_kb = shadow_kb_req 2.32 2.33 # Make sure there's enough RAM available for the domain 2.34 - balloon.free(m + sm * 1024) 2.35 + balloon.free(mem_kb + shadow_kb) 2.36 2.37 # Set up the shadow memory 2.38 - sm = xc.shadow_mem_control(self.domid, mb=sm) 2.39 - self.info['shadow_memory'] = sm 2.40 + shadow_cur = xc.shadow_mem_control(self.domid, shadow_kb * 1024) 2.41 + self.info['shadow_memory'] = shadow_cur 2.42 2.43 - init_reservation = self.info['memory'] * 1024 2.44 - if os.uname()[4] in ('ia64', 'ppc64'): 2.45 - # Workaround for architectures that don't yet support 2.46 - # ballooning. 2.47 - init_reservation = m 2.48 - # Following line from xiantao.zhang@intel.com 2.49 - # Needed for IA64 until supports ballooning -- okay for PPC64? 2.50 - xc.domain_setmaxmem(self.domid, m) 2.51 - 2.52 - xc.domain_memory_increase_reservation(self.domid, init_reservation, 2.53 - 0, 0) 2.54 + # initial memory allocation 2.55 + xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0) 2.56 2.57 self.createChannels() 2.58
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/python/xen/xend/arch.py Tue Aug 29 23:20:22 2006 +0100 3.3 @@ -0,0 +1,31 @@ 3.4 +#!/usr/bin/env python 3.5 +# 3.6 +# This library is free software; you can redistribute it and/or 3.7 +# modify it under the terms of version 2.1 of the GNU Lesser General Public 3.8 +# License as published by the Free Software Foundation. 3.9 +# 3.10 +# This library is distributed in the hope that it will be useful, 3.11 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 3.12 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 3.13 +# Lesser General Public License for more details. 3.14 +# 3.15 +# You should have received a copy of the GNU Lesser General Public 3.16 +# License along with this library; if not, write to the Free Software 3.17 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 3.18 +# 3.19 +# Copyright (C) IBM Corp. 2006 3.20 +# 3.21 +# Authors: Hollis Blanchard <hollisb@us.ibm.com> 3.22 + 3.23 +import os 3.24 + 3.25 +_types = { 3.26 + "i386": "x86", 3.27 + "i486": "x86", 3.28 + "i586": "x86", 3.29 + "i686": "x86", 3.30 + "ia64": "ia64", 3.31 + "ppc": "powerpc", 3.32 + "ppc64": "powerpc", 3.33 +} 3.34 +type = _types.get(os.uname()[4], "unknown")
4.1 --- a/tools/python/xen/xend/image.py Tue Aug 29 22:51:06 2006 +0100 4.2 +++ b/tools/python/xen/xend/image.py Tue Aug 29 23:20:22 2006 +0100 4.3 @@ -27,6 +27,8 @@ from xen.xend.XendError import VmError 4.4 from xen.xend.XendLogging import log 4.5 from xen.xend.server.netif import randomMAC 4.6 from xen.xend.xenstore.xswatch import xswatch 4.7 +from xen.xend import arch 4.8 +from xen.xend import FlatDeviceTree 4.9 4.10 4.11 xc = xen.lowlevel.xc.xc() 4.12 @@ -141,19 +143,10 @@ class ImageHandler: 4.13 raise VmError('Building domain failed: ostype=%s dom=%d err=%s' 4.14 % (self.ostype, self.vm.getDomid(), str(result))) 4.15 4.16 - 4.17 - def getDomainMemory(self, mem_kb): 4.18 - """@return The memory required, in KiB, by the domain to store the 4.19 - given amount, also in KiB.""" 4.20 - if os.uname()[4] != 'ia64': 4.21 - # A little extra because auto-ballooning is broken w.r.t. HVM 4.22 - # guests. Also, slack is necessary for live migration since that 4.23 - # uses shadow page tables. 4.24 - if 'hvm' in xc.xeninfo()['xen_caps']: 4.25 - mem_kb += 4*1024; 4.26 + def getRequiredMemory(self, mem_kb): 4.27 return mem_kb 4.28 4.29 - def getDomainShadowMemory(self, mem_kb): 4.30 + def getRequiredShadowMemory(self, mem_kb): 4.31 """@return The minimum shadow memory required, in KiB, for a domain 4.32 with mem_kb KiB of RAM.""" 4.33 # PV domains don't need any shadow memory 4.34 @@ -197,9 +190,39 @@ class LinuxImageHandler(ImageHandler): 4.35 ramdisk = self.ramdisk, 4.36 features = self.vm.getFeatures()) 4.37 4.38 -class HVMImageHandler(ImageHandler): 4.39 +class PPC_LinuxImageHandler(LinuxImageHandler): 4.40 + 4.41 + ostype = "linux" 4.42 + 4.43 + def configure(self, imageConfig, deviceConfig): 4.44 + LinuxImageHandler.configure(self, imageConfig, deviceConfig) 4.45 + self.imageConfig = imageConfig 4.46 + 4.47 + def buildDomain(self): 4.48 + store_evtchn = self.vm.getStorePort() 4.49 + console_evtchn = self.vm.getConsolePort() 4.50 4.51 - ostype = "hvm" 4.52 + log.debug("dom = %d", self.vm.getDomid()) 4.53 + log.debug("image = %s", self.kernel) 4.54 + log.debug("store_evtchn = %d", store_evtchn) 4.55 + log.debug("console_evtchn = %d", console_evtchn) 4.56 + log.debug("cmdline = %s", self.cmdline) 4.57 + log.debug("ramdisk = %s", self.ramdisk) 4.58 + log.debug("vcpus = %d", self.vm.getVCpuCount()) 4.59 + log.debug("features = %s", self.vm.getFeatures()) 4.60 + 4.61 + devtree = FlatDeviceTree.build(self) 4.62 + 4.63 + return xc.linux_build(dom = self.vm.getDomid(), 4.64 + image = self.kernel, 4.65 + store_evtchn = store_evtchn, 4.66 + console_evtchn = console_evtchn, 4.67 + cmdline = self.cmdline, 4.68 + ramdisk = self.ramdisk, 4.69 + features = self.vm.getFeatures(), 4.70 + arch_args = devtree.to_bin()) 4.71 + 4.72 +class HVMImageHandler(ImageHandler): 4.73 4.74 def configure(self, imageConfig, deviceConfig): 4.75 ImageHandler.configure(self, imageConfig, deviceConfig) 4.76 @@ -355,32 +378,6 @@ class HVMImageHandler(ImageHandler): 4.77 os.waitpid(self.pid, 0) 4.78 self.pid = 0 4.79 4.80 - def getDomainMemory(self, mem_kb): 4.81 - """@see ImageHandler.getDomainMemory""" 4.82 - if os.uname()[4] == 'ia64': 4.83 - page_kb = 16 4.84 - # ROM size for guest firmware, ioreq page and xenstore page 4.85 - extra_pages = 1024 + 2 4.86 - else: 4.87 - page_kb = 4 4.88 - # This was derived emperically: 4.89 - # 2.4 MB overhead per 1024 MB RAM + 8 MB constant 4.90 - # + 4 to avoid low-memory condition 4.91 - extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12; 4.92 - extra_pages = int( math.ceil( extra_mb*1024 / page_kb )) 4.93 - return mem_kb + extra_pages * page_kb 4.94 - 4.95 - def getDomainShadowMemory(self, mem_kb): 4.96 - """@return The minimum shadow memory required, in KiB, for a domain 4.97 - with mem_kb KiB of RAM.""" 4.98 - if os.uname()[4] in ('ia64', 'ppc64'): 4.99 - # Explicit shadow memory is not a concept 4.100 - return 0 4.101 - else: 4.102 - # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than 4.103 - # the minimum that Xen would allocate if no value were given. 4.104 - return 1024 * self.vm.getVCpuCount() + mem_kb / 256 4.105 - 4.106 def register_shutdown_watch(self): 4.107 """ add xen store watch on control/shutdown """ 4.108 self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \ 4.109 @@ -417,15 +414,51 @@ class HVMImageHandler(ImageHandler): 4.110 4.111 return 1 # Keep watching 4.112 4.113 -"""Table of image handler classes for virtual machine images. Indexed by 4.114 -image type. 4.115 -""" 4.116 -imageHandlerClasses = {} 4.117 +class IA64_HVM_ImageHandler(HVMImageHandler): 4.118 + 4.119 + ostype = "hvm" 4.120 + 4.121 + def getRequiredMemory(self, mem_kb): 4.122 + page_kb = 16 4.123 + # ROM size for guest firmware, ioreq page and xenstore page 4.124 + extra_pages = 1024 + 2 4.125 + return mem_kb + extra_pages * page_kb 4.126 + 4.127 + def getRequiredShadowMemory(self, mem_kb): 4.128 + # Explicit shadow memory is not a concept 4.129 + return 0 4.130 + 4.131 +class X86_HVM_ImageHandler(HVMImageHandler): 4.132 + 4.133 + ostype = "hvm" 4.134 4.135 + def getRequiredMemory(self, mem_kb): 4.136 + page_kb = 4 4.137 + # This was derived emperically: 4.138 + # 2.4 MB overhead per 1024 MB RAM + 8 MB constant 4.139 + # + 4 to avoid low-memory condition 4.140 + extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12; 4.141 + extra_pages = int( math.ceil( extra_mb*1024 / page_kb )) 4.142 + return mem_kb + extra_pages * page_kb 4.143 4.144 -for h in LinuxImageHandler, HVMImageHandler: 4.145 - imageHandlerClasses[h.ostype] = h 4.146 + def getRequiredShadowMemory(self, mem_kb): 4.147 + # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than 4.148 + # the minimum that Xen would allocate if no value were given. 4.149 + return 1024 * self.vm.getVCpuCount() + mem_kb / 256 4.150 4.151 +_handlers = { 4.152 + "powerpc": { 4.153 + "linux": PPC_LinuxImageHandler, 4.154 + }, 4.155 + "ia64": { 4.156 + "linux": LinuxImageHandler, 4.157 + "hvm": IA64_HVM_ImageHandler, 4.158 + }, 4.159 + "x86": { 4.160 + "linux": LinuxImageHandler, 4.161 + "hvm": X86_HVM_ImageHandler, 4.162 + }, 4.163 +} 4.164 4.165 def findImageHandlerClass(image): 4.166 """Find the image handler class for an image config. 4.167 @@ -433,10 +466,10 @@ def findImageHandlerClass(image): 4.168 @param image config 4.169 @return ImageHandler subclass or None 4.170 """ 4.171 - ty = sxp.name(image) 4.172 - if ty is None: 4.173 + type = sxp.name(image) 4.174 + if type is None: 4.175 raise VmError('missing image type') 4.176 - imageClass = imageHandlerClasses.get(ty) 4.177 - if imageClass is None: 4.178 - raise VmError('unknown image type: ' + ty) 4.179 - return imageClass 4.180 + try: 4.181 + return _handlers[arch.type][type] 4.182 + except KeyError: 4.183 + raise VmError('unknown image type: ' + type)