ia64/xen-unstable
changeset 5343:4c7d2c6e932a
bitkeeper revision 1.1662.1.7 (42a47555156iGoOjUyZtvbuMFZHXkg)
XendDomainInfo.py:
Move guest image handling into seperate file.
image.py:
new file
Signed-off-by: Mike Wray <mike.wray@hp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
XendDomainInfo.py:
Move guest image handling into seperate file.
image.py:
new file
Signed-off-by: Mike Wray <mike.wray@hp.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author | cl349@firebug.cl.cam.ac.uk |
---|---|
date | Mon Jun 06 16:09:57 2005 +0000 (2005-06-06) |
parents | a3b60b641063 |
children | e1cd6bd22fb9 |
files | .rootkeys tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py |
line diff
1.1 --- a/.rootkeys Mon Jun 06 15:06:50 2005 +0000 1.2 +++ b/.rootkeys Mon Jun 06 16:09:57 2005 +0000 1.3 @@ -849,6 +849,7 @@ 40c9c4686jruMyZIqiaZRMiMoqMJtg tools/pyt 1.4 40c9c468xzANp6o2D_MeCYwNmOIUsQ tools/python/xen/xend/XendVnet.py 1.5 40c9c468x191zetrVlMnExfsQWHxIQ tools/python/xen/xend/__init__.py 1.6 40c9c468S2YnCEKmk4ey8XQIST7INg tools/python/xen/xend/encode.py 1.7 +42a475165HuglqWwNi2fjqNOIHbIKQ tools/python/xen/xend/image.py 1.8 4266169ezWIlXSfY50n6HSoVFbosmw tools/python/xen/xend/scheduler.py 1.9 40c9c468IxQabrKJSWs0aEjl-27mRQ tools/python/xen/xend/server/SrvConsole.py 1.10 40c9c4689Io5bxfbYIfRiUvsiLX0EQ tools/python/xen/xend/server/SrvConsoleDir.py
2.1 --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jun 06 15:06:50 2005 +0000 2.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jun 06 16:09:57 2005 +0000 2.3 @@ -114,25 +114,6 @@ def get_config_handler(name): 2.4 """ 2.5 return config_handlers.get(name) 2.6 2.7 -"""Table of handlers for virtual machine images. 2.8 -Indexed by image type. 2.9 -""" 2.10 -image_handlers = {} 2.11 - 2.12 -def add_image_handler(name, h): 2.13 - """Add a handler for an image type 2.14 - @param name: image type 2.15 - @param h: handler: fn(config, name, memory, image) 2.16 - """ 2.17 - image_handlers[name] = h 2.18 - 2.19 -def get_image_handler(name): 2.20 - """Get the handler for an image type. 2.21 - @param name: image type 2.22 - @return: handler or None 2.23 - """ 2.24 - return image_handlers.get(name) 2.25 - 2.26 """Table of handlers for devices. 2.27 Indexed by device type. 2.28 """ 2.29 @@ -252,8 +233,6 @@ class XendDomainInfo: 2.30 self.name = None 2.31 self.memory = None 2.32 self.image = None 2.33 - self.ramdisk = None 2.34 - self.cmdline = None 2.35 2.36 self.channel = None 2.37 self.controllers = {} 2.38 @@ -278,8 +257,6 @@ class XendDomainInfo: 2.39 2.40 self.console_port = None 2.41 self.savedinfo = None 2.42 - self.image_handler = None 2.43 - self.is_vmx = False 2.44 self.vcpus = 1 2.45 self.bootloader = None 2.46 2.47 @@ -330,8 +307,6 @@ class XendDomainInfo: 2.48 console = self.getConsole() 2.49 if console: 2.50 s += " console=" + str(console.console_port) 2.51 - if self.image: 2.52 - s += " image=" + self.image 2.53 s += "" 2.54 return s 2.55 2.56 @@ -484,8 +459,8 @@ class XendDomainInfo: 2.57 # Initial domain create. 2.58 self.setName(sxp.child_value(config, 'name')) 2.59 self.check_name(self.name) 2.60 + self.init_image() 2.61 self.configure_cpus(config) 2.62 - self.find_image_handler() 2.63 self.init_domain() 2.64 self.register_domain() 2.65 self.configure_bootloader() 2.66 @@ -527,29 +502,24 @@ class XendDomainInfo: 2.67 except: 2.68 raise VmError('invalid vcpus value') 2.69 2.70 - def find_image_handler(self): 2.71 - """Construct the boot image for the domain. 2.72 - 2.73 - @return vm 2.74 + def init_image(self): 2.75 + """Create boot image handler for the domain. 2.76 """ 2.77 image = sxp.child_value(self.config, 'image') 2.78 if image is None: 2.79 raise VmError('missing image') 2.80 - image_name = sxp.name(image) 2.81 - if image_name is None: 2.82 - raise VmError('missing image name') 2.83 - if image_name == "vmx": 2.84 - self.is_vmx = True 2.85 - image_handler = get_image_handler(image_name) 2.86 - if image_handler is None: 2.87 - raise VmError('unknown image type: ' + image_name) 2.88 - self.image_handler = image_handler 2.89 - return self 2.90 + self.image = ImageHandler.create(self, image) 2.91 2.92 def construct_image(self): 2.93 - image = sxp.child_value(self.config, 'image') 2.94 - self.image_handler(self, image) 2.95 - return self 2.96 + """Construct the boot image for the domain. 2.97 + """ 2.98 + self.create_channel() 2.99 + self.image.createImage() 2.100 + #self.image.exportToDB() 2.101 + #if self.store_channel: 2.102 + # self.db.introduceDomain(self.id, 2.103 + # self.store_mfn, 2.104 + # self.store_channel) 2.105 2.106 def config_devices(self, name): 2.107 """Get a list of the 'device' nodes of a given type from the config. 2.108 @@ -596,7 +566,7 @@ class XendDomainInfo: 2.109 """Completely destroy the vm. 2.110 """ 2.111 self.cleanup() 2.112 - return self.destroy_domain() 2.113 + self.destroy_domain() 2.114 2.115 def destroy_domain(self): 2.116 """Destroy the vm's domain. 2.117 @@ -606,9 +576,15 @@ class XendDomainInfo: 2.118 if self.channel: 2.119 self.channel.close() 2.120 self.channel = None 2.121 + if self.image: 2.122 + try: 2.123 + self.image.destroy() 2.124 + self.image = None 2.125 + except: 2.126 + pass 2.127 if self.id is None: return 0 2.128 try: 2.129 - return xc.domain_destroy(dom=self.id) 2.130 + xc.domain_destroy(dom=self.id) 2.131 except Exception, err: 2.132 log.exception("Domain destroy failed: %s", self.name) 2.133 2.134 @@ -661,80 +637,11 @@ class XendDomainInfo: 2.135 cpu = int(sxp.child_value(self.config, 'cpu', '-1')) 2.136 except: 2.137 raise VmError('invalid cpu') 2.138 - cpu_weight = self.cpu_weight 2.139 - memory = memory * 1024 + self.pgtable_size(memory) 2.140 - dom = xc.domain_create(dom= dom) 2.141 - if self.bootloader: 2.142 - try: 2.143 - if kernel: os.unlink(kernel) 2.144 - if ramdisk: os.unlink(ramdisk) 2.145 - except OSError, e: 2.146 - log.warning('unable to unlink kernel/ramdisk: %s' %(e,)) 2.147 - 2.148 - if dom <= 0: 2.149 - raise VmError('Creating domain failed: name=%s memory=%d' 2.150 - % (self.name, memory)) 2.151 - xc.domain_setcpuweight(dom, cpu_weight) 2.152 - xc.domain_setmaxmem(dom, memory) 2.153 - xc.domain_memory_increase_reservation(dom, memory) 2.154 - if cpu != -1: 2.155 - xc.domain_pincpu(dom, 0, 1<<int(cpu)) 2.156 - log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, self.name, memory) 2.157 - self.setdom(dom) 2.158 - 2.159 - def build_domain(self, ostype, kernel, ramdisk, cmdline, memmap): 2.160 - """Build the domain boot image. 2.161 - """ 2.162 - if self.recreate or self.restore: return 2.163 - if not os.path.isfile(kernel): 2.164 - raise VmError('Kernel image does not exist: %s' % kernel) 2.165 - if ramdisk and not os.path.isfile(ramdisk): 2.166 - raise VmError('Kernel ramdisk does not exist: %s' % ramdisk) 2.167 - if len(cmdline) >= 256: 2.168 - log.warning('kernel cmdline too long, domain %d', self.id) 2.169 - dom = self.id 2.170 - buildfn = getattr(xc, '%s_build' % ostype) 2.171 - flags = 0 2.172 - if self.netif_backend: flags |= SIF_NET_BE_DOMAIN 2.173 - if self.blkif_backend: flags |= SIF_BLK_BE_DOMAIN 2.174 - #todo generalise this 2.175 - if ostype == "vmx": 2.176 - log.debug('building vmx domain') 2.177 - err = buildfn(dom = dom, 2.178 - image = kernel, 2.179 - control_evtchn = 0, 2.180 - memsize = self.memory, 2.181 - memmap = memmap, 2.182 - cmdline = cmdline, 2.183 - ramdisk = ramdisk, 2.184 - flags = flags) 2.185 - else: 2.186 - log.debug('building dom with %d vcpus', self.vcpus) 2.187 - err = buildfn(dom = dom, 2.188 - image = kernel, 2.189 - control_evtchn = self.channel.getRemotePort(), 2.190 - cmdline = cmdline, 2.191 - ramdisk = ramdisk, 2.192 - flags = flags, 2.193 - vcpus = self.vcpus) 2.194 - if err != 0: 2.195 - raise VmError('Building domain failed: type=%s dom=%d err=%d' 2.196 - % (ostype, dom, err)) 2.197 - 2.198 - def create_domain(self, ostype, kernel, ramdisk, cmdline, memmap=''): 2.199 - """Create a domain. Builds the image but does not configure it. 2.200 - 2.201 - @param ostype: OS type 2.202 - @param kernel: kernel image 2.203 - @param ramdisk: kernel ramdisk 2.204 - @param cmdline: kernel commandline 2.205 - """ 2.206 - 2.207 - self.create_channel() 2.208 - self.build_domain(ostype, kernel, ramdisk, cmdline, memmap) 2.209 - self.image = kernel 2.210 - self.ramdisk = ramdisk 2.211 - self.cmdline = cmdline 2.212 + dom = self.image.initDomain(self.id, self.memory, cpu, self.cpu_weight) 2.213 + log.debug('init_domain> Created domain=%d name=%s memory=%d', 2.214 + dom, self.name, self.memory) 2.215 + if not self.restore: 2.216 + self.setdom(dom) 2.217 2.218 def create_channel(self): 2.219 """Create the control channel to the domain. 2.220 @@ -773,43 +680,6 @@ class XendDomainInfo: 2.221 ctrl.initController(reboot=True) 2.222 else: 2.223 self.create_configured_devices() 2.224 - if self.is_vmx: 2.225 - self.create_vmx_model() 2.226 - 2.227 - def create_vmx_model(self): 2.228 - #todo: remove special case for vmx 2.229 - device_model = sxp.child_value(self.config, 'device_model') 2.230 - if not device_model: 2.231 - raise VmError("vmx: missing device model") 2.232 - device_config = sxp.child_value(self.config, 'device_config') 2.233 - if not device_config: 2.234 - raise VmError("vmx: missing device config") 2.235 - #todo: self.memory? 2.236 - memory = sxp.child_value(self.config, "memory") 2.237 - # Create an event channel 2.238 - device_channel = channel.eventChannel(0, self.id) 2.239 - # see if a vncviewer was specified 2.240 - # XXX RN: bit of a hack. should unify this, maybe stick in config space 2.241 - vncconnect="" 2.242 - image = sxp.child_value(self.config, "image") 2.243 - args = sxp.child_value(image, "args") 2.244 - if args: 2.245 - arg_list = string.split(args) 2.246 - for arg in arg_list: 2.247 - al = string.split(arg, '=') 2.248 - if al[0] == "VNC_VIEWER": 2.249 - vncconnect=" -v %s" % al[1] 2.250 - break 2.251 - 2.252 - # Execute device model. 2.253 - #todo: Error handling 2.254 - # XXX RN: note that the order of args matter! 2.255 - os.system(device_model 2.256 - + " -f %s" % device_config 2.257 - + vncconnect 2.258 - + " -d %d" % self.id 2.259 - + " -p %d" % device_channel['port1'] 2.260 - + " -m %s" % memory) 2.261 2.262 def device_create(self, dev_config): 2.263 """Create a new device. 2.264 @@ -862,9 +732,7 @@ class XendDomainInfo: 2.265 def configure_bootloader(self): 2.266 """Configure boot loader. 2.267 """ 2.268 - bl = sxp.child_value(self.config, "bootloader") 2.269 - if bl is not None: 2.270 - self.bootloader = bl 2.271 + self.bootloader = sxp.child_value(self.config, "bootloader") 2.272 2.273 def configure_console(self): 2.274 """Configure the vm console port. 2.275 @@ -1052,19 +920,6 @@ class XendDomainInfo: 2.276 log.warning("Unknown config field %s", field_name) 2.277 index[field_name] = field_index + 1 2.278 2.279 - def pgtable_size(self, memory): 2.280 - """Return the size of memory needed for 1:1 page tables for physical 2.281 - mode. 2.282 - 2.283 - @param memory: size in MB 2.284 - @return size in KB 2.285 - """ 2.286 - if self.is_vmx: 2.287 - # Logic x86-32 specific. 2.288 - # 1 page for the PGD + 1 pte page for 4MB of memory (rounded) 2.289 - return (1 + ((memory + 3) >> 2)) * 4 2.290 - return 0 2.291 - 2.292 def mem_target_set(self, target): 2.293 """Set domain memory target in pages. 2.294 """ 2.295 @@ -1091,83 +946,6 @@ class XendDomainInfo: 2.296 return 0 2.297 return timeout - (time.time() - self.shutdown_pending['start']) 2.298 2.299 -def vm_image_linux(vm, image): 2.300 - """Create a VM for a linux image. 2.301 - 2.302 - @param name: vm name 2.303 - @param memory: vm memory 2.304 - @param image: image config 2.305 - @return: vm 2.306 - """ 2.307 - kernel = sxp.child_value(image, "kernel") 2.308 - cmdline = "" 2.309 - ip = sxp.child_value(image, "ip", None) 2.310 - if ip: 2.311 - cmdline += " ip=" + ip 2.312 - root = sxp.child_value(image, "root") 2.313 - if root: 2.314 - cmdline += " root=" + root 2.315 - args = sxp.child_value(image, "args") 2.316 - if args: 2.317 - cmdline += " " + args 2.318 - ramdisk = sxp.child_value(image, "ramdisk", '') 2.319 - log.debug("creating linux domain with cmdline: %s" %(cmdline,)) 2.320 - vm.create_domain("linux", kernel, ramdisk, cmdline) 2.321 - return vm 2.322 - 2.323 -def vm_image_plan9(vm, image): 2.324 - """Create a VM for a Plan 9 image. 2.325 - 2.326 - name vm name 2.327 - memory vm memory 2.328 - image image config 2.329 - 2.330 - returns vm 2.331 - """ 2.332 - kernel = sxp.child_value(image, "kernel") 2.333 - cmdline = "" 2.334 - ip = sxp.child_value(image, "ip", "dhcp") 2.335 - if ip: 2.336 - cmdline += "ip=" + ip 2.337 - root = sxp.child_value(image, "root") 2.338 - if root: 2.339 - cmdline += "root=" + root 2.340 - args = sxp.child_value(image, "args") 2.341 - if args: 2.342 - cmdline += " " + args 2.343 - ramdisk = sxp.child_value(image, "ramdisk", '') 2.344 - log.debug("creating plan9 domain with cmdline: %s" %(cmdline,)) 2.345 - vm.create_domain("plan9", kernel, ramdisk, cmdline) 2.346 - return vm 2.347 - 2.348 -def vm_image_vmx(vm, image): 2.349 - """Create a VM for the VMX environment. 2.350 - 2.351 - @param name: vm name 2.352 - @param memory: vm memory 2.353 - @param image: image config 2.354 - @return: vm 2.355 - """ 2.356 - kernel = sxp.child_value(image, "kernel") 2.357 - cmdline = "" 2.358 - ip = sxp.child_value(image, "ip", "dhcp") 2.359 - if ip: 2.360 - cmdline += " ip=" + ip 2.361 - root = sxp.child_value(image, "root") 2.362 - if root: 2.363 - cmdline += " root=" + root 2.364 - args = sxp.child_value(image, "args") 2.365 - if args: 2.366 - cmdline += " " + args 2.367 - ramdisk = sxp.child_value(image, "ramdisk", '') 2.368 - memmap = sxp.child_value(vm.config, "memmap", '') 2.369 - memmap = sxp.parse(open(memmap))[0] 2.370 - from xen.util.memmap import memmap_parse 2.371 - memmap = memmap_parse(memmap) 2.372 - log.debug("creating vmx domain with cmdline: %s" %(cmdline,)) 2.373 - vm.create_domain("vmx", kernel, ramdisk, cmdline, memmap) 2.374 - return vm 2.375 - 2.376 def vm_field_ignore(vm, config, val, index): 2.377 """Dummy config field handler used for fields with built-in handling. 2.378 2.379 @@ -1197,9 +975,16 @@ def vm_field_maxmem(vm, config, val, ind 2.380 2.381 #============================================================================ 2.382 # Register image handlers. 2.383 -add_image_handler('linux', vm_image_linux) 2.384 -add_image_handler('plan9', vm_image_plan9) 2.385 -add_image_handler('vmx', vm_image_vmx) 2.386 +from image import \ 2.387 + addImageHandlerClass, \ 2.388 + ImageHandler, \ 2.389 + LinuxImageHandler, \ 2.390 + Plan9ImageHandler, \ 2.391 + VmxImageHandler 2.392 + 2.393 +addImageHandlerClass(LinuxImageHandler) 2.394 +addImageHandlerClass(Plan9ImageHandler) 2.395 +addImageHandlerClass(VmxImageHandler) 2.396 2.397 # Ignore the fields we already handle. 2.398 add_config_handler('name', vm_field_ignore)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/python/xen/xend/image.py Mon Jun 06 16:09:57 2005 +0000 3.3 @@ -0,0 +1,338 @@ 3.4 +import os 3.5 + 3.6 +import xen.lowlevel.xc; xc = xen.lowlevel.xc.new() 3.7 +from xen.xend import sxp 3.8 +from xen.xend.XendError import VmError 3.9 +from xen.xend.XendLogging import log 3.10 +#from xen.xend.xenstore import DBVar 3.11 + 3.12 +class ImageHandler: 3.13 + """Abstract base class for image handlers. 3.14 + 3.15 + initDomain() is called to initialise the domain memory. 3.16 + 3.17 + createImage() is called to configure and build the domain from its 3.18 + kernel image and ramdisk etc. 3.19 + 3.20 + The method buildDomain() is used to build the domain, and must be 3.21 + defined in a subclass. Usually this is the only method that needs 3.22 + defining in a subclass. 3.23 + 3.24 + The method createDeviceModel() is called to create the domain device 3.25 + model if it needs one. The default is to do nothing. 3.26 + 3.27 + The method destroy() is called when the domain is destroyed. 3.28 + The default is to do nothing. 3.29 + 3.30 + """ 3.31 + 3.32 + #====================================================================== 3.33 + # Class vars and methods. 3.34 + 3.35 + """Table of image handler classes for virtual machine images. 3.36 + Indexed by image type. 3.37 + """ 3.38 + imageHandlerClasses = {} 3.39 + 3.40 + def addImageHandlerClass(cls, h): 3.41 + """Add a handler class for an image type 3.42 + @param h: handler: ImageHandler subclass 3.43 + """ 3.44 + cls.imageHandlerClasses[h.ostype] = h 3.45 + 3.46 + addImageHandlerClass = classmethod(addImageHandlerClass) 3.47 + 3.48 + def findImageHandlerClass(cls, image): 3.49 + """Find the image handler class for an image config. 3.50 + 3.51 + @param image config 3.52 + @return ImageHandler subclass or None 3.53 + """ 3.54 + ty = sxp.name(image) 3.55 + if ty is None: 3.56 + raise VmError('missing image type') 3.57 + imageClass = cls.imageHandlerClasses.get(ty) 3.58 + if imageClass is None: 3.59 + raise VmError('unknown image type: ' + ty) 3.60 + return imageClass 3.61 + 3.62 + findImageHandlerClass = classmethod(findImageHandlerClass) 3.63 + 3.64 + def create(cls, vm, image): 3.65 + """Create an image handler for a vm. 3.66 + 3.67 + @param vm vm 3.68 + @param image image config 3.69 + @return ImageHandler instance 3.70 + """ 3.71 + imageClass = cls.findImageHandlerClass(image) 3.72 + return imageClass(vm, image) 3.73 + 3.74 + create = classmethod(create) 3.75 + 3.76 + #====================================================================== 3.77 + # Instance vars and methods. 3.78 + 3.79 + #db = None 3.80 + ostype = None 3.81 + 3.82 + config = None 3.83 + kernel = None 3.84 + ramdisk = None 3.85 + cmdline = None 3.86 + flags = 0 3.87 + 3.88 + #__exports__ = [ 3.89 + # DBVar('ostype', ty='str'), 3.90 + # DBVar('config', ty='sxpr'), 3.91 + # DBVar('kernel', ty='str'), 3.92 + # DBVar('ramdisk', ty='str'), 3.93 + # DBVar('cmdline', ty='str'), 3.94 + # DBVar('flags', ty='int'), 3.95 + # ] 3.96 + 3.97 + def __init__(self, vm, config): 3.98 + self.vm = vm 3.99 + #self.db = vm.db.addChild('/image') 3.100 + self.config = config 3.101 + 3.102 + #def exportToDB(self, save=False): 3.103 + # self.db.exportToDB(self, fields=self.__exports__, save=save) 3.104 + 3.105 + #def importFromDB(self): 3.106 + # self.db.importFromDB(self, fields=self.__exports__) 3.107 + 3.108 + def unlink(self, f): 3.109 + if not f: return 3.110 + try: 3.111 + os.unlink(f) 3.112 + except OSError, ex: 3.113 + log.warning("error removing bootloader file '%s': %s", f, ex) 3.114 + 3.115 + def initDomain(self, dom, memory, cpu, cpu_weight): 3.116 + """Initial domain create. 3.117 + 3.118 + @return domain id 3.119 + """ 3.120 + 3.121 + mem_kb = self.getDomainMemory(memory) 3.122 + if not self.vm.restore: 3.123 + dom = xc.domain_create(dom = dom or 0) 3.124 + # if bootloader, unlink here. But should go after buildDomain() ? 3.125 + if self.vm.bootloader: 3.126 + self.unlink(self.kernel) 3.127 + self.unlink(self.ramdisk) 3.128 + if dom <= 0: 3.129 + raise VmError('Creating domain failed: name=%s' % self.vm.name) 3.130 + log.debug("initDomain: cpu=%d mem_kb=%d dom=%d", cpu, mem_kb, dom) 3.131 + # xc.domain_setuuid(dom, uuid) 3.132 + xc.domain_setcpuweight(dom, cpu_weight) 3.133 + xc.domain_setmaxmem(dom, mem_kb) 3.134 + xc.domain_memory_increase_reservation(dom, mem_kb) 3.135 + if cpu != -1: 3.136 + xc.domain_pincpu(dom, 0, 1<<int(cpu)) 3.137 + return dom 3.138 + 3.139 + def createImage(self): 3.140 + """Entry point to create domain memory image. 3.141 + Override in subclass if needed. 3.142 + """ 3.143 + self.configure() 3.144 + self.createDomain() 3.145 + 3.146 + def configure(self): 3.147 + """Config actions common to all unix-like domains.""" 3.148 + self.kernel = sxp.child_value(self.config, "kernel") 3.149 + self.cmdline = "" 3.150 + ip = sxp.child_value(self.config, "ip", None) 3.151 + if ip: 3.152 + self.cmdline += " ip=" + ip 3.153 + root = sxp.child_value(self.config, "root") 3.154 + if root: 3.155 + self.cmdline += " root=" + root 3.156 + args = sxp.child_value(self.config, "args") 3.157 + if args: 3.158 + self.cmdline += " " + args 3.159 + self.ramdisk = sxp.child_value(self.config, "ramdisk", '') 3.160 + 3.161 + def createDomain(self): 3.162 + """Build the domain boot image. 3.163 + """ 3.164 + # Set params and call buildDomain(). 3.165 + self.flags = 0 3.166 + if self.vm.netif_backend: self.flags |= SIF_NET_BE_DOMAIN 3.167 + if self.vm.blkif_backend: self.flags |= SIF_BLK_BE_DOMAIN 3.168 + 3.169 + if self.vm.recreate or self.vm.restore: 3.170 + return 3.171 + if not os.path.isfile(self.kernel): 3.172 + raise VmError('Kernel image does not exist: %s' % self.kernel) 3.173 + if self.ramdisk and not os.path.isfile(self.ramdisk): 3.174 + raise VmError('Kernel ramdisk does not exist: %s' % self.ramdisk) 3.175 + if len(self.cmdline) >= 256: 3.176 + log.warning('kernel cmdline too long, domain %d', self.vm.getDomain()) 3.177 + 3.178 + log.info("buildDomain os=%s dom=%d vcpus=%d", self.ostype, 3.179 + self.vm.getDomain(), self.vm.vcpus) 3.180 + err = self.buildDomain() 3.181 + if err != 0: 3.182 + raise VmError('Building domain failed: ostype=%s dom=%d err=%d' 3.183 + % (self.ostype, self.vm.getDomain(), err)) 3.184 + 3.185 + def getDomainMemory(self, mem_mb): 3.186 + """Memory (in KB) the domain will need for mem_mb (in MB).""" 3.187 + return mem_mb * 1024 3.188 + 3.189 + def buildDomain(self): 3.190 + """Build the domain. Define in subclass.""" 3.191 + raise NotImplementedError() 3.192 + 3.193 + def createDeviceModel(self): 3.194 + """Create device model for the domain (define in subclass if needed).""" 3.195 + pass 3.196 + 3.197 + def destroy(self): 3.198 + """Extra cleanup on domain destroy (define in subclass if needed).""" 3.199 + pass 3.200 + 3.201 +addImageHandlerClass = ImageHandler.addImageHandlerClass 3.202 + 3.203 +class LinuxImageHandler(ImageHandler): 3.204 + 3.205 + ostype = "linux" 3.206 + 3.207 + def buildDomain(self): 3.208 + #if self.vm.store_channel: 3.209 + # store_evtchn = self.vm.store_channel.port2 3.210 + #else: 3.211 + # store_evtchn = 0 3.212 + d = xc.linux_build(dom = self.vm.getDomain(), 3.213 + image = self.kernel, 3.214 + control_evtchn = self.vm.channel.getRemotePort(), 3.215 + #store_evtchn = store_evtchn, 3.216 + cmdline = self.cmdline, 3.217 + ramdisk = self.ramdisk, 3.218 + flags = self.flags, 3.219 + vcpus = self.vm.vcpus) 3.220 + #if isinstance(d, dict): 3.221 + # self.vm.store_mfn = d.get('store_mfn') 3.222 + return 0 3.223 + 3.224 +class Plan9ImageHandler(ImageHandler): 3.225 + 3.226 + ostype = "plan9" 3.227 + 3.228 + def buildDomain(self): 3.229 + return xc.plan9_build(dom = self.vm.getDomain(), 3.230 + image = self.kernel, 3.231 + control_evtchn = self.vm.channel.getRemotePort(), 3.232 + cmdline = self.cmdline, 3.233 + ramdisk = self.ramdisk, 3.234 + flags = self.flags, 3.235 + vcpus = self.vm.vcpus) 3.236 + 3.237 +class VmxImageHandler(ImageHandler): 3.238 + 3.239 + #__exports__ = ImageHandler.__exports__ + [ 3.240 + # DBVar('memmap', ty='str'), 3.241 + # DBVar('memmap_value', ty='sxpr'), 3.242 + # # device channel? 3.243 + # ] 3.244 + 3.245 + ostype = "vmx" 3.246 + memmap = None 3.247 + memmap_value = None 3.248 + device_channel = None 3.249 + 3.250 + def createImage(self): 3.251 + """Create a VM for the VMX environment. 3.252 + """ 3.253 + self.configure() 3.254 + self.parseMemmap() 3.255 + self.createDomain() 3.256 + 3.257 + def buildDomain(self): 3.258 + return xc.vmx_build(dom = self.vm.getDomain(), 3.259 + image = self.kernel, 3.260 + control_evtchn = 0, 3.261 + memsize = self.vm.memory, 3.262 + memmap = self.memmap_value, 3.263 + cmdline = self.cmdline, 3.264 + ramdisk = self.ramdisk, 3.265 + flags = self.flags) 3.266 + 3.267 + def parseMemmap(self): 3.268 + self.memmap = sxp.child_value(self.vm.config, "memmap") 3.269 + if self.memmap is None: 3.270 + raise VmError("missing memmap") 3.271 + memmap = sxp.parse(open(self.memmap))[0] 3.272 + from xen.util.memmap import memmap_parse 3.273 + self.memmap_value = memmap_parse(memmap) 3.274 + 3.275 + def createDeviceModel_old(self): 3.276 + device_model = sxp.child_value(self.vm.config, 'device_model') 3.277 + if not device_model: 3.278 + raise VmError("vmx: missing device model") 3.279 + device_config = sxp.child_value(self.vm.config, 'device_config') 3.280 + if not device_config: 3.281 + raise VmError("vmx: missing device config") 3.282 + # Create an event channel. 3.283 + self.device_channel = channel.eventChannel(0, self.vm.getDomain()) 3.284 + # Execute device model. 3.285 + #todo: Error handling 3.286 + os.system(device_model 3.287 + + " -f %s" % device_config 3.288 + + " -d %d" % self.vm.getDomain() 3.289 + + " -p %d" % self.device_channel['port1'] 3.290 + + " -m %s" % self.vm.memory) 3.291 + 3.292 + def createDeviceModel(self): 3.293 + device_model = sxp.child_value(self.vm.config, 'device_model') 3.294 + if not device_model: 3.295 + raise VmError("vmx: missing device model") 3.296 + device_config = sxp.child_value(self.vm.config, 'device_config') 3.297 + if not device_config: 3.298 + raise VmError("vmx: missing device config") 3.299 + # Create an event channel 3.300 + self.device_channel = channel.eventChannel(0, self.vm.getDomain()) 3.301 + # Execute device model. 3.302 + #todo: Error handling 3.303 + # XXX RN: note that the order of args matter! 3.304 + os.system(device_model 3.305 + + " -f %s" % device_config 3.306 + + self.vncParams() 3.307 + + " -d %d" % self.vm.getDomain() 3.308 + + " -p %d" % self.device_channel['port1'] 3.309 + + " -m %s" % self.vm.memory) 3.310 + 3.311 + def vncParams(self): 3.312 + # see if a vncviewer was specified 3.313 + # XXX RN: bit of a hack. should unify this, maybe stick in config space 3.314 + vncconnect="" 3.315 + image = self.config 3.316 + args = sxp.child_value(image, "args") 3.317 + if args: 3.318 + arg_list = string.split(args) 3.319 + for arg in arg_list: 3.320 + al = string.split(arg, '=') 3.321 + if al[0] == "VNC_VIEWER": 3.322 + vncconnect=" -v %s" % al[1] 3.323 + break 3.324 + return vncconnect 3.325 + 3.326 + def destroy(self): 3.327 + channel.eventChannelClose(self.device_channel) 3.328 + 3.329 + def getDomainMemory(self, mem_mb): 3.330 + return (mem_mb * 1024) + self.getPageTableSize(mem_mb) 3.331 + 3.332 + def getPageTableSize(self, mem_mb): 3.333 + """Return the size of memory needed for 1:1 page tables for physical 3.334 + mode. 3.335 + 3.336 + @param mem_mb: size in MB 3.337 + @return size in KB 3.338 + """ 3.339 + # Logic x86-32 specific. 3.340 + # 1 page for the PGD + 1 pte page for 4MB of memory (rounded) 3.341 + return (1 + ((mem_mb + 3) >> 2)) * 4