mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
Update VM's VCPU handling to match the documentation wrt VCPUs_max and
VCPUs_at_startup. Add VM.set_VCPUs_number_live, VM.add_to_VCPUs_params_live,
VM_metrics.VCPUs_{CPU,flags,params}.
Use these new calls to implement xm vcpu-list and xm sched-credit through
the Xen-API. Mark a number of other calls as unimplemented through that API.
Signed-off-by: Tom Wilkie <tom.wilkie@gmail.com>
Signed-off-by: Ewan Mellor <ewan@xensource.com>
This commit is contained in:
1 parent
830355957c
commit
93fdf19076
7 files changed
+323
-100
No files matched your search
@@ -1034,9 +1034,8 @@ class XendAPI(object):
|
||||
|
||||
VM_attr_ro = ['power_state',
|
||||
'resident_on',
|
||||
'memory_static_max',
|
||||
'memory_static_max',
|
||||
'memory_static_min',
|
||||
'VCPUs_number',
|
||||
'consoles',
|
||||
'VIFs',
|
||||
'VBDs',
|
||||
@@ -1054,6 +1053,8 @@ class XendAPI(object):
|
||||
'auto_power_on',
|
||||
'memory_dynamic_max',
|
||||
'memory_dynamic_min',
|
||||
'VCPUs_max',
|
||||
'VCPUs_at_startup',
|
||||
'VCPUs_params',
|
||||
'actions_after_shutdown',
|
||||
'actions_after_reboot',
|
||||
@@ -1081,9 +1082,11 @@ class XendAPI(object):
|
||||
('suspend', None),
|
||||
('resume', None),
|
||||
('send_sysrq', None),
|
||||
('set_VCPUs_number_live', None),
|
||||
('add_to_HVM_boot_params', None),
|
||||
('remove_from_HVM_boot_params', None),
|
||||
('add_to_VCPUs_params', None),
|
||||
('add_to_VCPUs_params_live', None),
|
||||
('remove_from_VCPUs_params', None),
|
||||
('add_to_platform', None),
|
||||
('remove_from_platform', None),
|
||||
@@ -1104,6 +1107,8 @@ class XendAPI(object):
|
||||
'memory_dynamic_max',
|
||||
'memory_dynamic_min',
|
||||
'memory_static_min',
|
||||
'VCPUs_max',
|
||||
'VCPUs_at_startup',
|
||||
'VCPUs_params',
|
||||
'actions_after_shutdown',
|
||||
'actions_after_reboot',
|
||||
@@ -1150,10 +1155,6 @@ class XendAPI(object):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_success(dom.get_memory_static_min())
|
||||
|
||||
def VM_get_VCPUs_number(self, session, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_success(dom.getVCpuCount())
|
||||
|
||||
def VM_get_VIFs(self, session, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_success(dom.get_vifs())
|
||||
@@ -1178,6 +1179,14 @@ class XendAPI(object):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_success(dom.get_metrics())
|
||||
|
||||
def VM_get_VCPUs_max(self, _, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_todo()
|
||||
|
||||
def VM_get_VCPUs_at_startup(self, _, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
return xen_api_todo()
|
||||
|
||||
# attributes (rw)
|
||||
def VM_get_name_label(self, session, vm_ref):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
@@ -1302,6 +1311,36 @@ class XendAPI(object):
|
||||
dom.info['vcpus_params'][key] = value
|
||||
return self._VM_save(dom)
|
||||
|
||||
def VM_add_to_VCPUs_params_live(self, session, vm_ref, key, value):
|
||||
self.VM_add_to_VCPUs_params(session, vm_ref, key, value)
|
||||
self._VM_VCPUs_params_refresh(vm_ref)
|
||||
return xen_api_success_void()
|
||||
|
||||
def _VM_VCPUs_params_refresh(self, vm_ref):
|
||||
xendom = XendDomain.instance()
|
||||
xeninfo = xendom.get_vm_by_uuid(vm_ref)
|
||||
|
||||
#update the cpumaps
|
||||
for key, value in xeninfo.info['vcpus_params'].items():
|
||||
if key.startswith("cpumap"):
|
||||
vcpu = int(key[6:])
|
||||
try:
|
||||
xendom.domain_pincpu(xeninfo.getDomid(), vcpu, value)
|
||||
except Exception, ex:
|
||||
log.exception(ex)
|
||||
|
||||
#need to update sched params aswell
|
||||
if 'weight' in xeninfo.info['vcpus_params'] \
|
||||
and 'cap' in xeninfo.info['vcpus_params']:
|
||||
weight = xeninfo.info['vcpus_params']['weight']
|
||||
cap = xeninfo.info['vcpus_params']['cap']
|
||||
xendom.domain_sched_credit_set(xeninfo.getDomid(), weight, cap)
|
||||
|
||||
def VM_set_VCPUs_number_live(self, _, vm_ref, num):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
dom.setVCpuCount(int(num))
|
||||
return xen_api_success_void()
|
||||
|
||||
def VM_remove_from_VCPUs_params(self, session, vm_ref, key):
|
||||
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
|
||||
if 'vcpus_params' in dom.info \
|
||||
@@ -1450,7 +1489,8 @@ class XendAPI(object):
|
||||
'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
|
||||
'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
|
||||
'VCPUs_params': xeninfo.get_vcpus_params(),
|
||||
'VCPUs_number': xeninfo.getVCpuCount(),
|
||||
'VCPUs_at_startup': xeninfo.getVCpuCount(),
|
||||
'VCPUs_max': xeninfo.getVCpuCount(),
|
||||
'actions_after_shutdown': xeninfo.get_on_shutdown(),
|
||||
'actions_after_reboot': xeninfo.get_on_reboot(),
|
||||
'actions_after_suspend': xeninfo.get_on_suspend(),
|
||||
@@ -1472,6 +1512,7 @@ class XendAPI(object):
|
||||
'other_config': xeninfo.info.get('other_config', {}),
|
||||
'domid': domid is None and -1 or domid,
|
||||
'is_control_domain': xeninfo == xendom.privilegedDomain(),
|
||||
'metrics': xeninfo.get_metrics()
|
||||
}
|
||||
return xen_api_success(record)
|
||||
|
||||
@@ -1547,8 +1588,11 @@ class XendAPI(object):
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
VM_metrics_attr_ro = ['memory_actual',
|
||||
'vcpus_number',
|
||||
'vcpus_utilisation']
|
||||
'VCPUs_number',
|
||||
'VCPUs_utilisation',
|
||||
'VCPUs_CPU',
|
||||
'VCPUs_flags',
|
||||
'VCPUs_params']
|
||||
VM_metrics_attr_rw = []
|
||||
VM_metrics_methods = []
|
||||
|
||||
@@ -1564,11 +1608,21 @@ class XendAPI(object):
|
||||
def VM_metrics_get_memory_actual(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_memory_actual())
|
||||
|
||||
def VM_metrics_get_vcpus_number(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_vcpus_number())
|
||||
def VM_metrics_get_VCPUs_number(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_number())
|
||||
|
||||
def VM_metrics_get_VCPUs_utilisation(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_utilisation())
|
||||
|
||||
def VM_metrics_get_VCPUs_CPU(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_CPU())
|
||||
|
||||
def VM_metrics_get_VCPUs_flags(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_flags())
|
||||
|
||||
def VM_metrics_get_VCPUs_params(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_VCPUs_params())
|
||||
|
||||
def VM_metrics_get_vcpus_utilisation(self, _, ref):
|
||||
return xen_api_success(self._VM_metrics_get(ref).get_vcpus_utilisation())
|
||||
|
||||
# Xen API: Class VBD
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
@@ -81,18 +81,18 @@ def scrub_password(data):
|
||||
#
|
||||
# CPU fields:
|
||||
#
|
||||
# vcpus_number -- the maximum number of vcpus that this domain may ever have.
|
||||
# VCPUs_max -- 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
|
||||
# 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.
|
||||
# VCPUs_live -- the number of VCPUs currently up, as reported by Xen. This
|
||||
# is changed by changing vcpu_avail, and waiting for the
|
||||
# domain to respond.
|
||||
#
|
||||
@@ -103,7 +103,7 @@ def scrub_password(data):
|
||||
|
||||
XENAPI_CFG_TO_LEGACY_CFG = {
|
||||
'uuid': 'uuid',
|
||||
'vcpus_number': 'vcpus',
|
||||
'VCPUs_max': 'vcpus',
|
||||
'cpus': 'cpus',
|
||||
'name_label': 'name',
|
||||
'actions_after_shutdown': 'on_poweroff',
|
||||
@@ -139,9 +139,10 @@ XENAPI_CFG_TYPES = {
|
||||
'memory_dynamic_min': int,
|
||||
'memory_dynamic_max': int,
|
||||
'cpus': list,
|
||||
'vcpus_policy': str,
|
||||
'vcpus_params': dict,
|
||||
'vcpus_number': int,
|
||||
'VCPUs_max': int,
|
||||
'VCPUs_at_startup': int,
|
||||
'VCPUs_live': int,
|
||||
'actions_after_shutdown': str,
|
||||
'actions_after_reboot': str,
|
||||
'actions_after_crash': str,
|
||||
@@ -318,7 +319,9 @@ class XendConfig(dict):
|
||||
'cpus': [],
|
||||
'cpu_weight': 256,
|
||||
'cpu_cap': 0,
|
||||
'vcpus_number': 1,
|
||||
'VCPUs_max': 1,
|
||||
'VCPUs_live': 1,
|
||||
'VCPUs_at_startup': 1,
|
||||
'vcpus_params': {},
|
||||
'console_refs': [],
|
||||
'vif_refs': [],
|
||||
@@ -371,8 +374,8 @@ class XendConfig(dict):
|
||||
event)
|
||||
|
||||
def _vcpus_sanity_check(self):
|
||||
if 'vcpus_number' in self and 'vcpu_avail' not in self:
|
||||
self['vcpu_avail'] = (1 << self['vcpus_number']) - 1
|
||||
if 'VCPUs_max' in self and 'vcpu_avail' not in self:
|
||||
self['vcpu_avail'] = (1 << self['VCPUs_max']) - 1
|
||||
|
||||
def _uuid_sanity_check(self):
|
||||
"""Make sure UUID is in proper string format with hyphens."""
|
||||
@@ -406,7 +409,7 @@ class XendConfig(dict):
|
||||
def _dominfo_to_xapi(self, dominfo):
|
||||
self['domid'] = dominfo['domid']
|
||||
self['online_vcpus'] = dominfo['online_vcpus']
|
||||
self['vcpus_number'] = dominfo['max_vcpu_id'] + 1
|
||||
self['VCPUs_max'] = dominfo['max_vcpu_id'] + 1
|
||||
|
||||
self['memory_dynamic_min'] = dominfo['mem_kb'] * 1024
|
||||
self['memory_dynamic_max'] = dominfo['mem_kb'] * 1024
|
||||
@@ -562,12 +565,12 @@ class XendConfig(dict):
|
||||
image_vcpus = sxp.child_value(image_sxp, 'vcpus')
|
||||
if image_vcpus != None:
|
||||
try:
|
||||
if 'vcpus_number' not in cfg:
|
||||
cfg['vcpus_number'] = int(image_vcpus)
|
||||
elif cfg['vcpus_number'] != int(image_vcpus):
|
||||
cfg['vcpus_number'] = int(image_vcpus)
|
||||
if 'VCPUs_max' not in cfg:
|
||||
cfg['VCPUs_max'] = int(image_vcpus)
|
||||
elif cfg['VCPUs_max'] != int(image_vcpus):
|
||||
cfg['VCPUs_max'] = int(image_vcpus)
|
||||
log.warn('Overriding vcpus from %d to %d using image'
|
||||
'vcpus value.', cfg['vcpus_number'])
|
||||
'vcpus value.', cfg['VCPUs_max'])
|
||||
except ValueError, e:
|
||||
raise XendConfigError('integer expeceted: %s: %s' %
|
||||
image_sxp, e)
|
||||
|
||||
@@ -1230,7 +1230,9 @@ class XendDomain:
|
||||
try:
|
||||
rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
log.exception(ex)
|
||||
raise XendError("Cannot pin vcpu: %s to cpu: %s - %s" % \
|
||||
(v, cpumap, str(ex)))
|
||||
return rc
|
||||
|
||||
def domain_cpu_sedf_set(self, domid, period, slice_, latency, extratime,
|
||||
|
||||
@@ -614,9 +614,9 @@ class XendDomainInfo:
|
||||
sxpr = ['domain',
|
||||
['domid', self.domid],
|
||||
['name', self.info['name_label']],
|
||||
['vcpu_count', self.info['vcpus_number']]]
|
||||
['vcpu_count', self.info['VCPUs_max']]]
|
||||
|
||||
for i in range(0, self.info['vcpus_number']):
|
||||
for i in range(0, self.info['VCPUs_max']):
|
||||
info = xc.vcpu_getinfo(self.domid, i)
|
||||
|
||||
sxpr.append(['vcpu',
|
||||
@@ -678,7 +678,7 @@ class XendDomainInfo:
|
||||
# settings to take precedence over any entries in the store.
|
||||
if priv:
|
||||
xeninfo = dom_get(self.domid)
|
||||
self.info['vcpus_number'] = xeninfo['online_vcpus']
|
||||
self.info['VCPUs_max'] = xeninfo['online_vcpus']
|
||||
self.info['vcpu_avail'] = (1 << xeninfo['online_vcpus']) - 1
|
||||
|
||||
# read image value
|
||||
@@ -831,7 +831,7 @@ class XendDomainInfo:
|
||||
return 'offline'
|
||||
|
||||
result = {}
|
||||
for v in range(0, self.info['vcpus_number']):
|
||||
for v in range(0, self.info['VCPUs_max']):
|
||||
result["cpu/%d/availability" % v] = availability(v)
|
||||
return result
|
||||
|
||||
@@ -952,7 +952,7 @@ class XendDomainInfo:
|
||||
return self.info['features']
|
||||
|
||||
def getVCpuCount(self):
|
||||
return self.info['vcpus_number']
|
||||
return self.info['VCPUs_max']
|
||||
|
||||
def setVCpuCount(self, vcpus):
|
||||
if vcpus <= 0:
|
||||
@@ -964,16 +964,16 @@ class XendDomainInfo:
|
||||
# update dom differently depending on whether we are adjusting
|
||||
# vcpu number up or down, otherwise _vcpuDomDetails does not
|
||||
# disable the vcpus
|
||||
if self.info['vcpus_number'] > vcpus:
|
||||
if self.info['VCPUs_max'] > vcpus:
|
||||
# decreasing
|
||||
self._writeDom(self._vcpuDomDetails())
|
||||
self.info['vcpus_number'] = vcpus
|
||||
self.info['VCPUs_live'] = vcpus
|
||||
else:
|
||||
# same or increasing
|
||||
self.info['vcpus_number'] = vcpus
|
||||
self.info['VCPUs_live'] = vcpus
|
||||
self._writeDom(self._vcpuDomDetails())
|
||||
else:
|
||||
self.info['vcpus_number'] = vcpus
|
||||
self.info['VCPUs_live'] = vcpus
|
||||
xen.xend.XendDomain.instance().managed_config_save(self)
|
||||
log.info("Set VCPU count on domain %s to %d", self.info['name_label'],
|
||||
vcpus)
|
||||
@@ -1427,7 +1427,7 @@ class XendDomainInfo:
|
||||
self._recreateDom()
|
||||
|
||||
# Set maximum number of vcpus in domain
|
||||
xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
|
||||
xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max']))
|
||||
|
||||
# register the domain in the list
|
||||
from xen.xend import XendDomain
|
||||
@@ -1464,7 +1464,7 @@ class XendDomainInfo:
|
||||
# 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['vcpus_number']):
|
||||
for v in range(0, self.info['VCPUs_max']):
|
||||
xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
|
||||
|
||||
# Use architecture- and image-specific calculations to determine
|
||||
@@ -1860,7 +1860,7 @@ class XendDomainInfo:
|
||||
if arch.type == "x86":
|
||||
# 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
|
||||
# the minimum that Xen would allocate if no value were given.
|
||||
overhead_kb = self.info['vcpus_number'] * 1024 + \
|
||||
overhead_kb = self.info['VCPUs_max'] * 1024 + \
|
||||
(self.info['memory_static_max'] / 1024 / 1024) * 4
|
||||
overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
|
||||
# The domain might already have some shadow memory
|
||||
@@ -2258,8 +2258,8 @@ class XendDomainInfo:
|
||||
def get_vcpus_util(self):
|
||||
vcpu_util = {}
|
||||
xennode = XendNode.instance()
|
||||
if 'vcpus_number' in self.info and self.domid != None:
|
||||
for i in range(0, self.info['vcpus_number']):
|
||||
if 'VCPUs_max' in self.info and self.domid != None:
|
||||
for i in range(0, self.info['VCPUs_max']):
|
||||
util = xennode.get_vcpu_util(self.domid, i)
|
||||
vcpu_util[str(i)] = util
|
||||
|
||||
|
||||
@@ -13,9 +13,13 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#============================================================================
|
||||
# Copyright (c) 2006-2007 Xensource Inc.
|
||||
# Copyright (c) 2007 Tom Wilkie
|
||||
#============================================================================
|
||||
|
||||
from xen.xend.XendLogging import log
|
||||
import xen.lowlevel.xc
|
||||
|
||||
xc = xen.lowlevel.xc.xc()
|
||||
|
||||
instances = {}
|
||||
|
||||
@@ -46,25 +50,75 @@ class XendVMMetrics:
|
||||
return self.uuid
|
||||
|
||||
def get_memory_actual(self):
|
||||
return self.get_record()["memory_actual"]
|
||||
|
||||
def get_vcpus_number(self):
|
||||
return self.get_record()["vcpus_number"]
|
||||
|
||||
def get_vcpus_utilisation(self):
|
||||
return self.xend_domain_instance.get_vcpus_util()
|
||||
|
||||
def get_record(self):
|
||||
domInfo = self.xend_domain_instance.getDomInfo()
|
||||
if domInfo:
|
||||
return { 'uuid' : self.uuid,
|
||||
'memory_actual' : domInfo["mem_kb"] * 1024,
|
||||
'vcpus_number' : domInfo["online_vcpus"],
|
||||
'vcpus_utilisation' : self.get_vcpus_utilisation()
|
||||
}
|
||||
return domInfo["mem_kb"] * 1024
|
||||
else:
|
||||
return { 'uuid' : self.uuid,
|
||||
'memory_actual' : 0,
|
||||
'vcpus_number' : 0,
|
||||
'vcpus_utilisation' : {}
|
||||
}
|
||||
return 0
|
||||
|
||||
def get_VCPUs_number(self):
|
||||
domInfo = self.xend_domain_instance.getDomInfo()
|
||||
if domInfo:
|
||||
return domInfo["online_vcpus"]
|
||||
else:
|
||||
return 0
|
||||
|
||||
def get_VCPUs_utilisation(self):
|
||||
return self.xend_domain_instance.get_vcpus_util()
|
||||
|
||||
def get_VCPUs_CPU(self):
|
||||
domid = self.xend_domain_instance.getDomid()
|
||||
if domid is not None:
|
||||
vcpus_cpu = {}
|
||||
vcpus_max = self.xend_domain_instance.info['VCPUs_max']
|
||||
for i in range(0, vcpus_max):
|
||||
info = xc.vcpu_getinfo(domid, i)
|
||||
vcpus_cpu[i] = info['cpu']
|
||||
return vcpus_cpu
|
||||
else:
|
||||
return {}
|
||||
|
||||
def get_VCPUs_flags(self):
|
||||
domid = self.xend_domain_instance.getDomid()
|
||||
if domid is not None:
|
||||
vcpus_flags = {}
|
||||
vcpus_max = self.xend_domain_instance.info['VCPUs_max']
|
||||
for i in range(0, vcpus_max):
|
||||
info = xc.vcpu_getinfo(domid, i)
|
||||
flags = []
|
||||
def set_flag(flag):
|
||||
if info[flag] == 1:
|
||||
flags.append(flag)
|
||||
set_flag('blocked')
|
||||
set_flag('online')
|
||||
set_flag('running')
|
||||
vcpus_flags[i] = ",".join(flags)
|
||||
return vcpus_flags
|
||||
else:
|
||||
return {}
|
||||
|
||||
def get_VCPUs_params(self):
|
||||
domid = self.xend_domain_instance.getDomid()
|
||||
if domid is not None:
|
||||
params_live = {}
|
||||
vcpus_max = self.xend_domain_instance.info['VCPUs_max']
|
||||
for i in range(0, vcpus_max):
|
||||
info = xc.vcpu_getinfo(domid, i)
|
||||
params_live['cpumap%i' % i] = \
|
||||
",".join(map(str, info['cpumap']))
|
||||
|
||||
params_live.update(xc.sched_credit_domain_get(domid))
|
||||
|
||||
return params_live
|
||||
else:
|
||||
return {}
|
||||
|
||||
def get_record(self):
|
||||
return { 'uuid' : self.uuid,
|
||||
'memory_actual' : self.get_memory_actual(),
|
||||
'VCPUs_number' : self.get_VCPUs_number(),
|
||||
'VCPUs_utilisation' : self.get_VCPUs_utilisation(),
|
||||
'VCPUs_CPU' : self.get_VCPUs_CPU(),
|
||||
'VCPUs_flags' : self.get_VCPUs_flags(),
|
||||
'VCPUs_params' : self.get_VCPUs_params()
|
||||
}
|
||||
+142
-32
@@ -502,6 +502,13 @@ def get_default_Network():
|
||||
return [network_ref
|
||||
for network_ref in server.xenapi.network.get_all()][0]
|
||||
|
||||
class XenAPIUnsupportedException(Exception):
|
||||
pass
|
||||
|
||||
def xenapi_unsupported():
|
||||
if serverType == SERVER_XEN_API:
|
||||
raise XenAPIUnsupportedException, "This function is not supported by Xen-API"
|
||||
|
||||
def map2sxp(m):
|
||||
return [[k, m[k]] for k in m.keys()]
|
||||
|
||||
@@ -550,10 +557,13 @@ def err(msg):
|
||||
|
||||
|
||||
def get_single_vm(dom):
|
||||
uuids = server.xenapi.VM.get_by_name_label(dom)
|
||||
n = len(uuids)
|
||||
if n == 1:
|
||||
return uuids[0]
|
||||
if serverType == SERVER_XEN_API:
|
||||
uuids = server.xenapi.VM.get_by_name_label(dom)
|
||||
n = len(uuids)
|
||||
if n > 0:
|
||||
return uuids[0]
|
||||
else:
|
||||
raise OptionError("Domain '%s' not found." % dom)
|
||||
else:
|
||||
dominfo = server.xend.domain(dom, False)
|
||||
return dominfo['uuid']
|
||||
@@ -697,9 +707,9 @@ def getDomains(domain_names, state, full = 0):
|
||||
dom_metrics = server.xenapi.VM_metrics.get_record(dom_metrics_ref)
|
||||
dom_rec.update({'name': dom_rec['name_label'],
|
||||
'memory_actual': int(dom_metrics['memory_actual'])/1024,
|
||||
'vcpus': dom_metrics['vcpus_number'],
|
||||
'vcpus': dom_metrics['VCPUs_number'],
|
||||
'state': '-----',
|
||||
'cpu_time': dom_metrics['vcpus_utilisation']})
|
||||
'cpu_time': dom_metrics['VCPUs_utilisation']})
|
||||
|
||||
doms_sxp.append(['domain'] + map2sxp(dom_rec))
|
||||
doms_dict.append(dom_rec)
|
||||
@@ -885,11 +895,71 @@ def xm_label_list(doms):
|
||||
|
||||
|
||||
def xm_vcpu_list(args):
|
||||
if args:
|
||||
dominfo = map(server.xend.domain.getVCPUInfo, args)
|
||||
else:
|
||||
doms = server.xend.domains(False)
|
||||
dominfo = map(server.xend.domain.getVCPUInfo, doms)
|
||||
if serverType == SERVER_XEN_API:
|
||||
if args:
|
||||
vm_refs = map(get_single_vm, args)
|
||||
else:
|
||||
vm_refs = server.xenapi.VM.get_all()
|
||||
|
||||
vm_records = dict(map(lambda vm_ref:
|
||||
(vm_ref, server.xenapi.VM.get_record(
|
||||
vm_ref)),
|
||||
vm_refs))
|
||||
|
||||
vm_metrics = dict(map(lambda (ref, record):
|
||||
(ref,
|
||||
server.xenapi.VM_metrics.get_record(
|
||||
record['metrics'])),
|
||||
vm_records.items()))
|
||||
|
||||
dominfo = []
|
||||
|
||||
# vcpu_list doesn't list 'managed' domains
|
||||
# when they are not running, so filter them out
|
||||
|
||||
vm_refs = [vm_ref
|
||||
for vm_ref in vm_refs
|
||||
if vm_records[vm_ref]["power_state"] != "Halted"]
|
||||
|
||||
for vm_ref in vm_refs:
|
||||
info = ['domain',
|
||||
['domid', vm_records[vm_ref]['domid']],
|
||||
['name', vm_records[vm_ref]['name_label']],
|
||||
['vcpu_count', vm_records[vm_ref]['VCPUs_max']]]
|
||||
|
||||
|
||||
|
||||
for i in range(int(vm_records[vm_ref]['VCPUs_max'])):
|
||||
def chk_flag(flag):
|
||||
return vm_metrics[vm_ref]['VCPUs_flags'][str(i)] \
|
||||
.find(flag) > -1 and 1 or 0
|
||||
|
||||
vcpu_info = ['vcpu',
|
||||
['number',
|
||||
i],
|
||||
['online',
|
||||
chk_flag("online")],
|
||||
['blocked',
|
||||
chk_flag("blocked")],
|
||||
['running',
|
||||
chk_flag("running")],
|
||||
['cpu_time',
|
||||
vm_metrics[vm_ref]['VCPUs_utilisation'][str(i)]],
|
||||
['cpu',
|
||||
vm_metrics[vm_ref]['VCPUs_CPU'][str(i)]],
|
||||
['cpumap',
|
||||
vm_metrics[vm_ref]['VCPUs_params']\
|
||||
['cpumap%i' % i].split(",")]]
|
||||
|
||||
info.append(vcpu_info)
|
||||
|
||||
dominfo.append(info)
|
||||
else:
|
||||
if args:
|
||||
dominfo = map(server.xend.domain.getVCPUInfo, args)
|
||||
else:
|
||||
doms = server.xend.domains(False)
|
||||
dominfo = map(server.xend.domain.getVCPUInfo, doms)
|
||||
|
||||
print '%-32s %3s %5s %5s %5s %9s %s' % \
|
||||
('Name', 'ID', 'VCPU', 'CPU', 'State', 'Time(s)', 'CPU Affinity')
|
||||
@@ -947,16 +1017,20 @@ def xm_vcpu_list(args):
|
||||
cpumap = map(lambda x: int(x), cpumap)
|
||||
cpumap.sort()
|
||||
|
||||
for x in server.xend.node.info()[1:]:
|
||||
if len(x) > 1 and x[0] == 'nr_cpus':
|
||||
nr_cpus = int(x[1])
|
||||
# normalize cpumap by modulus nr_cpus, and drop duplicates
|
||||
cpumap = dict.fromkeys(
|
||||
map(lambda x: x % nr_cpus, cpumap)).keys()
|
||||
if len(cpumap) == nr_cpus:
|
||||
return "any cpu"
|
||||
break
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
nr_cpus = len(server.xenapi.host.get_host_CPUs(
|
||||
server.xenapi.session.get_this_host()))
|
||||
else:
|
||||
for x in server.xend.node.info()[1:]:
|
||||
if len(x) > 1 and x[0] == 'nr_cpus':
|
||||
nr_cpus = int(x[1])
|
||||
|
||||
# normalize cpumap by modulus nr_cpus, and drop duplicates
|
||||
cpumap = dict.fromkeys(
|
||||
map(lambda x: x % nr_cpus, cpumap)).keys()
|
||||
if len(cpumap) == nr_cpus:
|
||||
return "any cpu"
|
||||
|
||||
return format_pairs(list_to_rangepairs(cpumap))
|
||||
|
||||
name = get_info('name')
|
||||
@@ -1154,13 +1228,17 @@ def xm_vcpu_pin(args):
|
||||
return cpus
|
||||
|
||||
dom = args[0]
|
||||
vcpu = args[1]
|
||||
vcpu = int(args[1])
|
||||
if args[2] == 'all':
|
||||
cpumap = cpu_make_map('0-63')
|
||||
else:
|
||||
cpumap = cpu_make_map(args[2])
|
||||
|
||||
server.xend.domain.pincpu(dom, vcpu, cpumap)
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.add_to_VCPUs_params_live(
|
||||
get_single_vm(dom), "cpumap%i" % vcpu, ",".join(cpumap))
|
||||
else:
|
||||
server.xend.domain.pincpu(dom, vcpu, cpumap)
|
||||
|
||||
def xm_mem_max(args):
|
||||
arg_check(args, "mem-max", 2)
|
||||
@@ -1194,7 +1272,7 @@ def xm_vcpu_set(args):
|
||||
vcpus = int(args[1])
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.set_vcpus_live(get_single_vm(dom), vcpus)
|
||||
server.xenapi.VM.set_VCPUs_number_live(get_single_vm(dom), vcpus)
|
||||
else:
|
||||
server.xend.domain.setVCpuCount(dom, vcpus)
|
||||
|
||||
@@ -1231,6 +1309,8 @@ def xm_domname(args):
|
||||
print sxp.child_value(dom, 'name')
|
||||
|
||||
def xm_sched_sedf(args):
|
||||
xenapi_unsupported()
|
||||
|
||||
def ns_to_ms(val):
|
||||
return float(val) * 0.000001
|
||||
|
||||
@@ -1355,10 +1435,21 @@ def xm_sched_credit(args):
|
||||
|
||||
for d in doms:
|
||||
try:
|
||||
info = server.xend.domain.sched_credit_get(d['domid'])
|
||||
if serverType == SERVER_XEN_API:
|
||||
info = server.xenapi.VM_metrics.get_VCPUs_params(
|
||||
server.xenapi.VM.get_metrics(
|
||||
get_single_vm(d['name'])))
|
||||
else:
|
||||
info = server.xend.domain.sched_credit_get(d['domid'])
|
||||
except xmlrpclib.Fault:
|
||||
pass
|
||||
|
||||
if 'weight' not in info or 'cap' not in info:
|
||||
# domain does not support sched-credit?
|
||||
info = {'weight': -1, 'cap': -1}
|
||||
|
||||
info['weight'] = int(info['weight'])
|
||||
info['cap'] = int(info['cap'])
|
||||
|
||||
info['name'] = d['name']
|
||||
info['domid'] = int(d['domid'])
|
||||
@@ -1368,10 +1459,20 @@ def xm_sched_credit(args):
|
||||
# place holder for system-wide scheduler parameters
|
||||
err("No domain given.")
|
||||
usage('sched-credit')
|
||||
|
||||
result = server.xend.domain.sched_credit_set(domid, weight, cap)
|
||||
if result != 0:
|
||||
err(str(result))
|
||||
|
||||
if serverType == SERVER_XEN_API:
|
||||
server.xenapi.VM.add_to_VCPUs_params_live(
|
||||
get_single_vm(domid),
|
||||
"weight",
|
||||
weight)
|
||||
server.xenapi.VM.add_to_VCPUs_params_live(
|
||||
get_single_vm(domid),
|
||||
"cap",
|
||||
cap)
|
||||
else:
|
||||
result = server.xend.domain.sched_credit_set(domid, weight, cap)
|
||||
if result != 0:
|
||||
err(str(result))
|
||||
|
||||
def xm_info(args):
|
||||
arg_check(args, "info", 0)
|
||||
@@ -1754,6 +1855,7 @@ def xm_block_list(args):
|
||||
% ni)
|
||||
|
||||
def xm_vtpm_list(args):
|
||||
xenapi_unsupported()
|
||||
(use_long, params) = arg_check_for_resource_list(args, "vtpm-list")
|
||||
|
||||
dom = params[0]
|
||||
@@ -1883,7 +1985,10 @@ def xm_network_attach(args):
|
||||
record = vif_record
|
||||
for key in keys[:-1]:
|
||||
record = record[key]
|
||||
record[keys[-1]] = val
|
||||
record[keys[-1]] = val
|
||||
|
||||
def get_net_from_bridge(bridge):
|
||||
raise "Not supported just yet"
|
||||
|
||||
vif_conv = {
|
||||
'type':
|
||||
@@ -1991,6 +2096,7 @@ def xm_network_detach(args):
|
||||
|
||||
|
||||
def xm_vnet_list(args):
|
||||
xenapi_unsupported()
|
||||
try:
|
||||
(options, params) = getopt.gnu_getopt(args, 'l', ['long'])
|
||||
except getopt.GetoptError, opterr:
|
||||
@@ -2019,6 +2125,7 @@ def xm_vnet_list(args):
|
||||
print vnet, ex
|
||||
|
||||
def xm_vnet_create(args):
|
||||
xenapi_unsupported()
|
||||
arg_check(args, "vnet-create", 1)
|
||||
conf = args[0]
|
||||
if not os.access(conf, os.R_OK):
|
||||
@@ -2028,6 +2135,7 @@ def xm_vnet_create(args):
|
||||
server.xend_vnet_create(conf)
|
||||
|
||||
def xm_vnet_delete(args):
|
||||
xenapi_unsupported()
|
||||
arg_check(args, "vnet-delete", 1)
|
||||
vnet = args[0]
|
||||
server.xend_vnet_delete(vnet)
|
||||
@@ -2044,7 +2152,7 @@ commands = {
|
||||
"domid": xm_domid,
|
||||
"domname": xm_domname,
|
||||
"dump-core": xm_dump_core,
|
||||
"reboot": xm_reboot,
|
||||
"reboot": xm_reboot,
|
||||
"rename": xm_rename,
|
||||
"restore": xm_restore,
|
||||
"resume": xm_resume,
|
||||
@@ -2228,6 +2336,8 @@ def _run_cmd(cmd, cmd_name, args):
|
||||
err(str(e))
|
||||
_usage(cmd_name)
|
||||
print e.usage
|
||||
except XenAPIUnsupportedException, e:
|
||||
err(str(e))
|
||||
except Exception, e:
|
||||
if serverType != SERVER_XEN_API:
|
||||
from xen.util import security
|
||||
|
||||
@@ -253,11 +253,11 @@ class xenapi_create:
|
||||
get_child_node_attribute(vm, "memory", "dynamic_max"),
|
||||
"memory_dynamic_min":
|
||||
get_child_node_attribute(vm, "memory", "dynamic_min"),
|
||||
"vcpus_params":
|
||||
"VCPUs_params":
|
||||
get_child_nodes_as_dict(vm, "vcpu_param", "key", "value"),
|
||||
"vcpus_max":
|
||||
"VCPUs_max":
|
||||
vm.attributes["vcpus_max"].value,
|
||||
"vcpus_at_startup":
|
||||
"VCPUs_at_startup":
|
||||
vm.attributes["vcpus_at_startup"].value,
|
||||
"actions_after_shutdown":
|
||||
vm.attributes["actions_after_shutdown"].value,
|
||||
|
||||