[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Fix the handling of VCPUs, specifically wrt the broken VCPU hotplugging, bug
# HG changeset patch # User emellor@ewan # Node ID 6f71824a45c19e860a3655dd8e76a83e047c84d2 # Parent 6e5463aec499333e9d4f91f612981aeb1f576445 Fix the handling of VCPUs, specifically wrt the broken VCPU hotplugging, bug #280. The cpu/<id>/availability paths had moved into /vm, but that is not easily accessible by the hotplugging driver, so I have created a /vm entry called vcpu_avail, so that the setting migrates along with the domain, and moved the cpu/<id> ones back to /local/domain. Don't try and destroy the domain twice if it fails within construct. This wasn't harming anything, but there's no need. Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx> diff -r 6e5463aec499 -r 6f71824a45c1 tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Oct 5 16:48:36 2005 +++ b/tools/python/xen/xend/XendDomainInfo.py Wed Oct 5 17:06:42 2005 @@ -111,6 +111,8 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [ ('name', str), ('ssidref', int), + ('vcpus', int), + ('vcpu_avail', int), ('cpu_weight', float), ('bootloader', str), ('on_poweroff', str), @@ -119,6 +121,27 @@ ] +# +# There are a number of CPU-related fields: +# +# vcpus: the number of virtual CPUs this domain is configured to use. +# vcpu_avail: a bitmap telling the guest domain whether it may use each of +# its VCPUs. This is translated to +# <dompath>/cpu/<id>/availability = {online,offline} for use +# by the guest domain. +# vcpu_to_cpu: the current mapping between virtual CPUs and the physical +# CPU it is using. +# cpumap: a list of bitmaps, one for each VCPU, giving the physical +# CPUs that that VCPU may use. +# cpu: a configuration setting requesting that VCPU 0 is pinned to +# the specified physical CPU. +# +# vcpus and vcpu_avail settings persist with the VM (i.e. they are persistent +# across save, restore, migrate, and restart). The other settings are only +# specific to the domain, so are lost when the VM moves. +# + + def create(config): """Create a VM from a configuration. @@ -134,6 +157,7 @@ vm.refreshShutdown() return vm except: + log.exception('Domain construction failed') vm.destroy() raise @@ -200,7 +224,7 @@ raise VmError('Invalid ssidref in config: %s' % exn) domid = xc.domain_create(ssidref = ssidref) - if domid <= 0: + if domid < 0: raise VmError('Creating domain failed for restore') try: vm = XendDomainInfo(uuid, parseConfig(config), domid) @@ -240,12 +264,12 @@ for e in ROUNDTRIPPING_CONFIG_ENTRIES: result[e[0]] = get_cfg(e[0], e[1]) - result['memory'] = get_cfg('memory', int) - result['mem_kb'] = get_cfg('mem_kb', int) - result['maxmem'] = get_cfg('maxmem', int) - result['maxmem_kb'] = get_cfg('maxmem_kb', int) - result['cpu'] = get_cfg('cpu', int) - result['image'] = get_cfg('image') + result['memory'] = get_cfg('memory', int) + result['mem_kb'] = get_cfg('mem_kb', int) + result['maxmem'] = get_cfg('maxmem', int) + result['maxmem_kb'] = get_cfg('maxmem_kb', int) + result['cpu'] = get_cfg('cpu', int) + result['image'] = get_cfg('image') try: if result['image']: @@ -338,7 +362,7 @@ self.uuid = uuid self.info = info - if domid: + if domid is not None: self.domid = domid elif 'dom' in info: self.domid = int(info['dom']) @@ -382,6 +406,8 @@ ("on_reboot", str), ("on_crash", str), ("image", str), + ("vcpus", int), + ("vcpu_avail", int), ("start_time", float)) from_store = self.gatherVm(*params) @@ -393,13 +419,13 @@ devconfig = self.getDeviceConfigurations(c) if devconfig: device.extend(map(lambda x: (c, x), devconfig)) - useIfNeeded('device', device) def validateInfo(self): """Validate and normalise the info block. This has either been parsed - by parseConfig, or received from xc through recreate. + by parseConfig, or received from xc through recreate and augmented by + the current store contents. """ def defaultInfo(name, val): if not self.infoIsSet(name): @@ -413,6 +439,8 @@ defaultInfo('on_crash', lambda: "restart") defaultInfo('cpu', lambda: None) defaultInfo('cpu_weight', lambda: 1.0) + defaultInfo('vcpus', lambda: 1) + defaultInfo('vcpu_avail', lambda: (1 << self.info['vcpus']) - 1) defaultInfo('bootloader', lambda: None) defaultInfo('backend', lambda: []) defaultInfo('device', lambda: []) @@ -499,12 +527,6 @@ raise VmError('invalid restart event: %s = %s' % (event, str(self.info[event]))) - if 'cpumap' not in self.info: - if [self.info['vcpus'] == 1]: - self.info['cpumap'] = [1]; - else: - raise VmError('Cannot create CPU map') - except KeyError, exn: log.exception(exn) raise VmError('Unspecified domain detail: %s' % str(exn)) @@ -552,7 +574,8 @@ if self.infoIsSet('image'): to_store['image'] = sxp.to_string(self.info['image']) - for k in ['name', 'ssidref', 'on_poweroff', 'on_reboot', 'on_crash']: + for k in ['name', 'ssidref', 'on_poweroff', 'on_reboot', 'on_crash', + 'vcpus', 'vcpu_avail']: if self.infoIsSet(k): to_store[k] = str(self.info[k]) @@ -572,6 +595,15 @@ for (k, v) in self.info.items(): if v: to_store[k] = str(v) + + def availability(n): + if self.info['vcpu_avail'] & (1 << n): + return 'online' + else: + return 'offline' + + for v in range(0, self.info['vcpus']): + to_store["cpu/%d/availability" % v] = availability(v) log.debug("Storing domain details: %s" % str(to_store)) @@ -916,7 +948,8 @@ if self.infoIsSet('cpu_time'): sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) sxpr.append(['vcpus', self.info['vcpus']]) - sxpr.append(['cpumap', self.info['cpumap']]) + if self.infoIsSet('cpumap'): + sxpr.append(['cpumap', self.info['cpumap']]) if self.infoIsSet('vcpu_to_cpu'): sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]]) sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()]) @@ -986,27 +1019,21 @@ self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref']) - if self.domid <= 0: + if self.domid < 0: raise VmError('Creating domain failed: name=%s' % self.info['name']) - try: - self.dompath = DOMROOT + str(self.domid) - - # Ensure that the domain entry is clean. This prevents a stale - # shutdown_start_time from killing the domain, for example. - self.removeDom() - - self.initDomain() - self.construct_image() - self.configure() - self.storeVmDetails() - self.storeDomDetails() - except: - log.exception('Domain construction failed') - self.destroy() - raise VmError('Creating domain failed: name=%s' % - self.info['name']) + self.dompath = DOMROOT + str(self.domid) + + # Ensure that the domain entry is clean. This prevents a stale + # shutdown_start_time from killing the domain, for example. + self.removeDom() + + self.initDomain() + self.construct_image() + self.configure() + self.storeVmDetails() + self.storeDomDetails() def initDomain(self): @@ -1041,13 +1068,6 @@ self.domid, self.info['name'], self.info['memory_KiB']) - def configure_vcpus(self): - d = {} - for v in range(0, self.info['vcpus']): - d["cpu/%d/availability" % v] = "online" - self.writeVm(d) - - def construct_image(self): """Construct the boot image for the domain. """ @@ -1055,7 +1075,6 @@ self.image.createImage() IntroduceDomain(self.domid, self.store_mfn, self.store_channel.port1, self.dompath) - self.configure_vcpus() ## public: @@ -1376,10 +1395,13 @@ log.error("Invalid VCPU %d" % vcpu) return if int(state) == 0: + self.info['vcpu_avail'] &= ~(1 << vcpu) availability = "offline" else: + self.info['vcpu_avail'] &= (1 << vcpu) availability = "online" - self.storeVm("cpu/%d/availability" % vcpu, availability) + self.storeVm('vcpu_avail', self.info['vcpu_avail']) + self.storeDom("cpu/%d/availability" % vcpu, availability) def send_sysrq(self, key=0): self.storeDom("control/sysrq", '%c' % key) @@ -1397,7 +1419,6 @@ pass else: raise - self.configure_vcpus() def dom0_enforce_vcpus(self): _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |