diff options
Diffstat (limited to 'tools/python/xen/xend/XendDomainInfo.py')
-rw-r--r-- | tools/python/xen/xend/XendDomainInfo.py | 137 |
1 files changed, 124 insertions, 13 deletions
diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 05647c83ab..22a0a8b282 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -20,6 +20,7 @@ from twisted.internet import defer import xen.lowlevel.xc; xc = xen.lowlevel.xc.new() import xen.util.ip from xen.util.ip import _readline, _readlines +from xen.xend.server import channel import sxp @@ -319,6 +320,9 @@ class XendDomainInfo: self.restart_time = None self.console_port = None self.savedinfo = None + self.image_handler = None + self.is_vmx = 0 + self.vcpus = 1 def setdom(self, dom): """Set the domain id. @@ -446,7 +450,13 @@ class XendDomainInfo: cpu = sxp.child_value(config, 'cpu') if self.recreate and self.dom and cpu is not None: xc.domain_pincpu(self.dom, int(cpu)) + try: + image = sxp.child_value(self.config, 'image') + self.vcpus = int(sxp.child_value(image, 'vcpus')) + except: + raise VmError('invalid vcpus value') + self.find_image_handler() self.init_domain() self.configure_console() self.configure_backends() @@ -463,7 +473,7 @@ class XendDomainInfo: raise return deferred - def construct_image(self): + def find_image_handler(self): """Construct the boot image for the domain. @return vm @@ -474,10 +484,17 @@ class XendDomainInfo: image_name = sxp.name(image) if image_name is None: raise VmError('missing image name') + if image_name == "vmx": + self.is_vmx = 1 image_handler = get_image_handler(image_name) if image_handler is None: raise VmError('unknown image type: ' + image_name) - image_handler(self, image) + self.image_handler = image_handler + return self + + def construct_image(self): + image = sxp.child_value(self.config, 'image') + self.image_handler(self, image) return self def config_devices(self, name): @@ -650,6 +667,7 @@ class XendDomainInfo: """ self.release_vifs() self.release_vbds() + self.release_usbifs() self.devices = {} self.device_index = {} @@ -674,6 +692,15 @@ class XendDomainInfo: log.debug("Destroying vbds for domain %d", self.dom) ctrl.destroy() + def release_usbifs(self): + """Release vm virtual USB devices (usbifs). + """ + if self.dom is None: return + ctrl = xend.usbif_get(self.dom) + if ctrl: + log.debug("Destroying usbifs for domain %d", self.dom) + ctrl.destroy() + def show(self): """Print virtual machine info. """ @@ -712,7 +739,8 @@ class XendDomainInfo: except: raise VmError('invalid cpu') cpu_weight = self.cpu_weight - dom = xc.domain_create(dom= dom, mem_kb= memory * 1024, + memory = memory * 1024 + self.pgtable_size(memory) + dom = xc.domain_create(dom= dom, mem_kb= memory, cpu= cpu, cpu_weight= cpu_weight) if dom <= 0: raise VmError('Creating domain failed: name=%s memory=%d' @@ -720,7 +748,7 @@ class XendDomainInfo: log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, name, memory) self.setdom(dom) - def build_domain(self, ostype, kernel, ramdisk, cmdline): + def build_domain(self, ostype, kernel, ramdisk, cmdline, memmap): """Build the domain boot image. """ if self.recreate or self.restore: return @@ -735,17 +763,29 @@ class XendDomainInfo: flags = 0 if self.netif_backend: flags |= SIF_NET_BE_DOMAIN if self.blkif_backend: flags |= SIF_BLK_BE_DOMAIN - err = buildfn(dom = dom, - image = kernel, - control_evtchn = self.console.getRemotePort(), - cmdline = cmdline, - ramdisk = ramdisk, - flags = flags) + if ostype == "vmx": + err = buildfn(dom = dom, + image = kernel, + control_evtchn = 0, + memsize = self.memory, + memmap = memmap, + cmdline = cmdline, + ramdisk = ramdisk, + flags = flags) + else: + log.warning('building dom with %d vcpus', self.vcpus) + err = buildfn(dom = dom, + image = kernel, + control_evtchn = self.console.getRemotePort(), + cmdline = cmdline, + ramdisk = ramdisk, + flags = flags, + vcpus = self.vcpus) if err != 0: raise VmError('Building domain failed: type=%s dom=%d err=%d' % (ostype, dom, err)) - def create_domain(self, ostype, kernel, ramdisk, cmdline): + def create_domain(self, ostype, kernel, ramdisk, cmdline, memmap=''): """Create a domain. Builds the image but does not configure it. @param ostype: OS type @@ -760,7 +800,7 @@ class XendDomainInfo: else: self.console = xendConsole.console_create( self.dom, console_port=self.console_port) - self.build_domain(ostype, kernel, ramdisk, cmdline) + self.build_domain(ostype, kernel, ramdisk, cmdline, memmap) self.image = kernel self.ramdisk = ramdisk self.cmdline = cmdline @@ -804,6 +844,18 @@ class XendDomainInfo: index[dev_name] = dev_index + 1 deferred = defer.DeferredList(dlist, fireOnOneErrback=1) deferred.addErrback(dlist_err) + if self.is_vmx: + device_model = sxp.child_value(self.config, 'device_model') + device_config = sxp.child_value(self.config, 'device_config') + memory = sxp.child_value(self.config, "memory") + # Create an event channel + device_channel = channel.eventChannel(0, self.dom) + # Fork and exec device_model -f device_config <port> + os.system(device_model + + " -f %s" % device_config + + " -d %d" % self.dom + + " -p %d" % device_channel['port1'] + + " -m %s &" % memory) return deferred def device_create(self, dev_config): @@ -963,6 +1015,8 @@ class XendDomainInfo: self.blkif_backend = 1 elif name == 'netif': self.netif_backend = 1 + elif name == 'usbif': + self.usbif_backend = 1 else: raise VmError('invalid backend type:' + str(name)) @@ -1041,6 +1095,18 @@ class XendDomainInfo: d.addErrback(dlist_err) return d + def pgtable_size(self, memory): + """Return the size of memory needed for 1:1 page tables for physical + mode. + + @param memory: size in MB + @return size in KB + """ + if self.is_vmx: + # Logic x86-32 specific. + # 1 page for the PGD + 1 pte page for 4MB of memory (rounded) + return (1 + ((memory + 3) >> 2)) * 4 + return 0 def vm_image_linux(vm, image): """Create a VM for a linux image. @@ -1091,7 +1157,32 @@ def vm_image_plan9(vm, image): vm.create_domain("plan9", kernel, ramdisk, cmdline) return vm - +def vm_image_vmx(vm, image): + """Create a VM for the VMX environment. + + @param name: vm name + @param memory: vm memory + @param image: image config + @return: vm + """ + kernel = sxp.child_value(image, "kernel") + cmdline = "" + ip = sxp.child_value(image, "ip", "dhcp") + if ip: + cmdline += " ip=" + ip + root = sxp.child_value(image, "root") + if root: + cmdline += " root=" + root + args = sxp.child_value(image, "args") + if args: + cmdline += " " + args + ramdisk = sxp.child_value(image, "ramdisk", '') + memmap = sxp.child_value(vm.config, "memmap", '') + memmap = sxp.parse(open(memmap))[0] + from xen.util.memmap import memmap_parse + memmap = memmap_parse(memmap) + vm.create_domain("vmx", kernel, ramdisk, cmdline, memmap) + return vm def vm_dev_vif(vm, val, index, change=0): """Create a virtual network interface (vif). @@ -1117,6 +1208,23 @@ def vm_dev_vif(vm, val, index, change=0): defer.addCallback(cbok) return defer +def vm_dev_usb(vm, val, index): + """Attach the relevant physical ports to the domains' USB interface. + + @param vm: virtual machine + @param val: USB interface config + @param index: USB interface index + @return: deferred + """ + ctrl = xend.usbif_create(vm.dom, recreate=vm.recreate) + log.debug("Creating USB interface dom=%d", vm.dom) + defer = ctrl.attachDevice(val, recreate=vm.recreate) + def cbok(path): + vm.add_device('usb', val[1][1]) + return path + defer.addCallback(cbok) + return defer + def vm_dev_vbd(vm, val, index, change=0): """Create a virtual block device (vbd). @@ -1215,11 +1323,13 @@ def vm_field_maxmem(vm, config, val, index): # Register image handlers. add_image_handler('linux', vm_image_linux) add_image_handler('plan9', vm_image_plan9) +add_image_handler('vmx', vm_image_vmx) # Register device handlers. add_device_handler('vif', vm_dev_vif) add_device_handler('vbd', vm_dev_vbd) add_device_handler('pci', vm_dev_pci) +add_device_handler('usb', vm_dev_usb) # Ignore the fields we already handle. add_config_handler('name', vm_field_ignore) @@ -1230,6 +1340,7 @@ add_config_handler('console', vm_field_ignore) add_config_handler('image', vm_field_ignore) add_config_handler('device', vm_field_ignore) add_config_handler('backend', vm_field_ignore) +add_config_handler('vcpus', vm_field_ignore) # Register other config handlers. add_config_handler('maxmem', vm_field_maxmem) |