else:
return data
+#
+# CPU fields:
+#
+# vcpus_number -- the maximum number of vcpus that this domain may ever have.
+# aka XendDomainInfo.getVCpuCount().
+# vcpus -- the legacy configuration name for above.
+# max_vcpu_id -- vcpus_number - 1. This is given to us by Xen.
+#
+# cpus -- the list of pCPUs available to each vCPU.
+#
+# 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.
+# online_vpcus -- the number of VCPUs currently up, as reported by Xen. This
+# is changed by changing vcpu_avail, and waiting for the
+# domain to respond.
+#
+
# Mapping from XendConfig configuration keys to the old
# legacy configuration keys that map directly.
'uuid': str,
'name': str,
'vcpus': int,
- 'vcpu_avail': int,
+ 'vcpu_avail': long,
'memory': int,
'shadow_memory': int,
'maxmem': int,
'cpu_weight': 256,
'cpu_cap': 0,
'vcpus_number': 1,
- 'online_vcpus': 1,
- 'max_vcpu_id': 0,
- 'vcpu_avail': 1,
'console_refs': [],
'vif_refs': [],
'vbd_refs': [],
event)
def _vcpus_sanity_check(self):
- if self.get('vcpus_number') != None:
+ if 'vcpus_number' in self and 'vcpu_avail' not in self:
self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
def _uuid_sanity_check(self):
def _dominfo_to_xapi(self, dominfo):
self['domid'] = dominfo['domid']
self['online_vcpus'] = dominfo['online_vcpus']
- self['max_vcpu_id'] = dominfo['max_vcpu_id']
+ self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
self['cpu_time'] = dominfo['cpu_time']/1e9
self['memory_dynamic_max'] = self['memory_static_max']
self['memory_dynamic_min'] = self['memory_static_min']
- # make sure max_vcpu_id is set correctly
- self['max_vcpu_id'] = self['vcpus_number'] - 1
-
# set device references in the configuration
self['devices'] = cfg.get('devices', {})
_set_cfg_if_exists('on_xend_stop')
_set_cfg_if_exists('on_xend_start')
_set_cfg_if_exists('vcpu_avail')
- _set_cfg_if_exists('max_vcpu_id') # needed for vcpuDomDetails
_set_cfg_if_exists('cpu_weight')
_set_cfg_if_exists('cpu_cap')
# Parse and store runtime configuration
_set_cfg_if_exists('start_time')
- _set_cfg_if_exists('online_vcpus')
_set_cfg_if_exists('cpu_time')
_set_cfg_if_exists('shutdown_reason')
_set_cfg_if_exists('up_time')
#log.setLevel(logging.TRACE)
-#
-# 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.
-# 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):
"""Creates and start a VM using the supplied configuration.
['name', self.info['name_label']],
['vcpu_count', self.info['vcpus_number']]]
- for i in range(0, self.info['max_vcpu_id']+1):
+ for i in range(0, self.info['vcpus_number']):
info = xc.vcpu_getinfo(self.domid, i)
sxpr.append(['vcpu',
self._writeDom(self._vcpuDomDetails())
else:
self.info['vcpus_number'] = vcpus
- self.info['online_vcpus'] = vcpus
xen.xend.XendDomain.instance().managed_config_save(self)
+ log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
+ vcpus)
def getLabel(self):
return security.get_security_info(self.info, 'label')
# this is done prior to memory allocation to aide in memory
# distribution for NUMA systems.
if self.info['cpus'] is not None and len(self.info['cpus']) > 0:
- for v in range(0, self.info['max_vcpu_id']+1):
+ for v in range(0, self.info['vcpus_number']):
xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
# Use architecture- and image-specific calculations to determine
# TODO: spec says that key is int, however, python does not allow
# non-string keys to dictionaries.
vcpu_util = {}
- if 'max_vcpu_id' in self.info and self.domid != None:
- for i in range(0, self.info['max_vcpu_id']+1):
+ if 'vcpus_number' in self.info and self.domid != None:
+ for i in range(0, self.info['vcpus_number']):
info = xc.vcpu_getinfo(self.domid, i)
vcpu_util[str(i)] = info['cpu_time']/1000000000.0
# xm config file
def parseDeviceModelArgs(self, imageConfig, deviceConfig):
dmargs = [ 'boot', 'fda', 'fdb', 'soundhw',
- 'localtime', 'serial', 'stdvga', 'isa', 'vcpus',
+ 'localtime', 'serial', 'stdvga', 'isa',
'acpi', 'usb', 'usbdevice', 'keymap' ]
- ret = []
hvmDeviceConfig = imageConfig['hvm']['devices']
-
+
+ ret = ['-vcpus', str(self.vm.getVCpuCount())]
+
for a in dmargs:
v = hvmDeviceConfig.get(a)
fn=set_int, default=1,
use="# of Virtual CPUS in domain.")
+gopts.var('vcpu_avail', val='VCPUS',
+ fn=set_long, default=None,
+ use="Bitmask for virtual CPUs to make available immediately.")
+
gopts.var('cpu_cap', val='CAP',
fn=set_int, default=None,
use="""Set the maximum amount of cpu.
map(add_conf, ['name', 'memory', 'maxmem', 'shadow_memory',
'restart', 'on_poweroff',
- 'on_reboot', 'on_crash', 'vcpus', 'features',
+ 'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features',
'on_xend_start', 'on_xend_stop'])
if vals.uuid is not None:
up_time = time.time() - start_time
return {
- 'domid' : get_info('domid', str, ''),
- 'name' : get_info('name', str, '??'),
+ 'domid' : get_info('domid', str, ''),
+ 'name' : get_info('name', str, '??'),
'mem' : get_info('memory_dynamic_min', int, 0),
- 'vcpus' : get_info('online_vcpus', int, 0),
- 'state' : get_info('state', str, ''),
- 'cpu_time' : get_info('cpu_time', float, 0),
+ 'state' : get_info('state', str, ''),
+ 'cpu_time' : get_info('cpu_time', float, 0.0),
+ # VCPUs is the number online when the VM is up, or the number
+ # configured otherwise.
+ 'vcpus' : get_info('online_vcpus', int,
+ get_info('vcpus', int, 0)),
'up_time' : up_time,
'seclabel' : security.get_security_printlabel(info),
}
opt.opts.err('Invalid value: ' + str(v))
opt.set(v)
+def set_long(opt, k, v):
+ """Set an option to a long integer value."""
+ try:
+ v = long(v)
+ except:
+ opt.opts.err('Invalid value: ' + str(v))
+ opt.set(v)
+
def set_float(opt, k, v):
"""Set an option to a float value."""
try: