cpupools, xend: Add missing file XendCPUPool.py

Signed-off-by: Juergen Gross <juergen.gross@ts.fujitsu.com>
This commit is contained in:
Keir Fraser committed 2010-04-23 15:04:26 +01:00
1 parent 6cf942ffa2
commit 8149e93337
1 file changed
+905
+905
View File
@@ -0,0 +1,905 @@
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (c) 2009 Fujitsu Technology Solutions.
#============================================================================
""" CPU Pool support including XEN-API and Legacy API.
"""
import types
import threading
import re
import xen.lowlevel.xc
import XendNode
import XendDomain
from xen.xend.XendLogging import log
from xen.xend.XendBase import XendBase
from xen.xend import XendAPIStore
from xen.xend.XendConstants import XS_POOLROOT
from xen.xend import uuid as genuuid
from xen.xend.XendError import VmError, XendAPIError, PoolError
from xen.xend.xenstore.xstransact import xstransact
from xen.util.sxputils import sxp2map, map2sxp
XEND_ERROR_INTERNAL = 'INTERNAL_ERROR'
XEND_ERROR_UNKOWN_SCHED_POLICY = 'UNKOWN_SCHED_POLICY'
XEND_ERROR_BAD_POOL_STATE = 'POOL_BAD_STATE'
XEND_ERROR_POOL_PARAM = 'PARAMETER_ERROR'
XEND_ERROR_INSUFFICIENT_CPUS = 'INSUFFICIENT_CPUS'
XEND_ERROR_POOL_RECONF = 'POOL_RECONF'
XEND_ERROR_INVALID_CPU = 'INVAILD_CPU'
XEND_ERROR_LAST_CPU_NOT_REM = 'LAST_CPU_NOT_REMOVEABLE'
XEN_SCHEDULER_TO_ID = {
'credit2': xen.lowlevel.xc.XEN_SCHEDULER_CREDIT2,
'credit' : xen.lowlevel.xc.XEN_SCHEDULER_CREDIT,
'sedf' : xen.lowlevel.xc.XEN_SCHEDULER_SEDF,
}
xc = xen.lowlevel.xc.xc()
class XendCPUPool(XendBase):
""" CPU Pool management.
@ivar pool_lock: Lock to secure modification of pool data
@type pool_lock: Rlock
"""
pool_lock = threading.RLock()
def getClass(cls):
return "cpu_pool"
def getAttrRO(cls):
attrRO = ['resident_on',
'started_VMs',
'host_CPUs',
'activated',
]
return XendBase.getAttrRO() + attrRO
def getAttrRW(cls):
attrRW = ['name_label',
'name_description',
'auto_power_on',
'ncpu',
'sched_policy',
'proposed_CPUs',
'other_config',
]
return XendBase.getAttrRW() + attrRW
def getMethods(cls):
methods = ['destroy',
'activate',
'deactivate',
'add_host_CPU_live',
'remove_host_CPU_live',
'add_to_proposed_CPUs',
'remove_from_proposed_CPUs',
'add_to_other_config',
'remove_from_other_config',
]
return XendBase.getMethods() + methods
def getFuncs(cls):
funcs = ['create',
'get_by_name_label',
]
return XendBase.getFuncs() + funcs
getClass = classmethod(getClass)
getAttrRO = classmethod(getAttrRO)
getAttrRW = classmethod(getAttrRW)
getMethods = classmethod(getMethods)
getFuncs = classmethod(getFuncs)
#
# XenAPI function calls
#
def create(cls, record):
""" Create a new managed pool instance.
@param record: attributes of pool
@type record: dict
@return: uuid of created pool
@rtype: str
"""
new_uuid = genuuid.createString()
XendCPUPool(record, new_uuid)
XendNode.instance().save_cpu_pools()
return new_uuid
create = classmethod(create)
def get_by_name_label(cls, name_label):
""" Query a Pool(ref) by its name.
@return: ref of pool
@rtype: str
"""
cls.pool_lock.acquire()
try:
return [ inst.get_uuid()
for inst in XendAPIStore.get_all(cls.getClass())
if inst.name_label == name_label
]
finally:
cls.pool_lock.release()
get_by_name_label = classmethod(get_by_name_label)
def get_cpu_pool_by_cpu_ref(cls, host_cpu):
""" Query cpu_pool ref the given cpu belongs to.
@param host_cpu: ref of host_cpu to lookup
@type host_cpu: str
@return: list cpu_pool refs (list contains not more than one element)
@rtype: list of str
"""
node = XendNode.instance()
cpu_nr = node.get_host_cpu_field(host_cpu, 'number')
for pool_rec in xc.cpupool_getinfo():
if cpu_nr in pool_rec['cpulist']:
# pool found; return the ref
return cls.query_pool_ref(pool_rec['cpupool'])
return []
get_cpu_pool_by_cpu_ref = classmethod(get_cpu_pool_by_cpu_ref)
def get_all_managed(cls):
""" Query all managed pools.
@return: uuids of all managed pools
@rtype: list of str
"""
cls.pool_lock.acquire()
try:
managed_pools = [ inst.get_uuid()
for inst in XendAPIStore.get_all(cls.getClass())
if inst.is_managed() ]
finally:
cls.pool_lock.release()
return managed_pools
get_all_managed = classmethod(get_all_managed)
#
# XenAPI methods calls
#
def __init__(self, record, new_uuid, managed_pool=True):
XendBase.__init__(self, new_uuid, record)
try:
self._managed = managed_pool
self.name_label = None
name = record.get('name_label', 'Pool-Unnamed')
self._checkName(name)
self.name_label = name
self.name_description = record.get('name_description',
self.name_label)
self.proposed_cpus = [ int(cpu)
for cpu in record.get('proposed_CPUs', []) ]
self.auto_power_on = bool(record.get('auto_power_on', False))
self.ncpu = int(record.get('ncpu', 1))
self.sched_policy = record.get('sched_policy', '')
self.other_config = record.get('other_config', {})
except Exception, ex:
XendBase.destroy(self)
raise ex
def get_resident_on(self):
""" Always return uuid of own node.
@return: uuid of this node
@rytpe: str
"""
return XendNode.instance().uuid
def get_started_VMs(self):
""" Query all VMs currently assigned to pool.
@return: ref of all VMs assigned to pool; if pool is not active,
an empty list will be returned
@rtype: list of str
"""
if self.get_activated():
# search VMs related to this pool
pool_id = self.query_pool_id()
started_VMs = [ vm.get_uuid()
for vm in XendDomain.instance().list('all')
if vm.get_cpu_pool() == pool_id ]
else:
# pool not active, so it couldn't have any started VMs
started_VMs = []
return started_VMs
def get_host_CPUs(self):
""" Query all cpu refs of this pool currently asisgned .
- Read pool id of this pool from xenstore
- Read cpu configuration from hypervisor
- lookup cpu number -> cpu ref
@return: host_cpu refs
@rtype: list of str
"""
if self.get_activated():
node = XendNode.instance()
pool_id = self.query_pool_id()
if pool_id == None:
raise PoolError(XEND_ERROR_INTERNAL,
[self.getClass(), 'get_host_CPUs'])
cpus = []
for pool_rec in xc.cpupool_getinfo():
if pool_rec['cpupool'] == pool_id:
cpus = pool_rec['cpulist']
# query host_cpu ref for any cpu of the pool
host_CPUs = [ cpu_ref
for cpu_ref in node.get_host_cpu_refs()
if node.get_host_cpu_field(cpu_ref, 'number')
in cpus ]
else:
# pool not active, so it couldn't have any assigned cpus
host_CPUs = []
return host_CPUs
def get_activated(self):
""" Query if the pool is registered in XendStore.
If pool uuid is not in XenStore, the pool is not activated.
@return: True, if activated
@rtype: bool
"""
return self.query_pool_id() != None
def get_name_label(self):
return self.name_label
def get_name_description(self):
return self.name_description
def get_auto_power_on(self):
return self.auto_power_on
def get_ncpu(self):
return self.ncpu
def get_sched_policy(self):
if len(self.sched_policy) == 0:
# default scheduler selected
return XendNode.instance().get_vcpus_policy()
else:
return self.sched_policy
def get_proposed_CPUs(self):
return [ str(cpu) for cpu in self.proposed_cpus ]
def get_other_config(self):
return self.other_config
def set_name_label(self, name_label):
self._checkName(name_label)
self.name_label = name_label
if self._managed:
XendNode.instance().save_cpu_pools()
def set_name_description(self, name_descr):
self.name_description = name_descr
if self._managed:
XendNode.instance().save_cpu_pools()
def set_auto_power_on(self, auto_power_on):
self.auto_power_on = bool(int(auto_power_on))
if self._managed:
XendNode.instance().save_cpu_pools()
def set_ncpu(self, ncpu):
_ncpu = int(ncpu)
if _ncpu < 1:
raise PoolError(XEND_ERROR_POOL_PARAM, 'ncpu')
self.ncpu = _ncpu
if self._managed:
XendNode.instance().save_cpu_pools()
def set_sched_policy(self, sched_policy):
if self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'activated')
self.sched_policy = sched_policy
if self._managed:
XendNode.instance().save_cpu_pools()
def set_proposed_CPUs(self, proposed_cpus):
if self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'activated')
self.proposed_cpus = [ int(cpu) for cpu in proposed_cpus ]
if self._managed:
XendNode.instance().save_cpu_pools()
def set_other_config(self, other_config):
self.other_config = other_config
if self._managed:
XendNode.instance().save_cpu_pools()
def destroy(self):
""" In order to destroy a cpu pool, it must be deactivated """
self.pool_lock.acquire()
try:
if self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'activated')
XendBase.destroy(self)
finally:
self.pool_lock.release()
XendNode.instance().save_cpu_pools()
def activate(self):
""" Create pool in hypervisor and add cpus.
Preconditions:
- pool not already active
- enough unbound cpus available
Actions:
- create pool in hypervisor
- select free cpus (preferred from proposed_CPUs list) and bind it to
the pool
- create entries in Xenstore
"""
self.pool_lock.acquire()
try:
if self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'activated')
sched_policy = self.get_sched_policy()
if sched_policy not in XEN_SCHEDULER_TO_ID.keys():
raise PoolError(XEND_ERROR_UNKOWN_SCHED_POLICY)
unbound_cpus = set(self.unbound_cpus())
if len(unbound_cpus) < self.ncpu:
raise PoolError(XEND_ERROR_INSUFFICIENT_CPUS,
[str(self.ncpu), str(len(unbound_cpus))])
# build list of cpu numbers to bind to pool
cpu_set = set(self.proposed_cpus).intersection(unbound_cpus)
if len(cpu_set) < self.ncpu:
pool_cpus = (list(cpu_set) +
list(unbound_cpus.difference(cpu_set)))
else:
pool_cpus = list(cpu_set)
pool_cpus = pool_cpus[0:self.ncpu]
# create pool in hypervisor
pool_id = xc.cpupool_create(
sched = XEN_SCHEDULER_TO_ID.get(sched_policy, 0))
self.update_XS(pool_id)
# add cpus
for cpu in pool_cpus:
xc.cpupool_addcpu(pool_id, cpu)
finally:
self.pool_lock.release()
def deactivate(self):
""" Delete pool in hypervisor
Preconditions:
- pool is activated
- no running VMs in pool
Actions:
- call hypervisor for deletion
- remove path of pool in xenstore
"""
self.pool_lock.acquire()
try:
if not self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'deactivated')
if len(self.get_started_VMs()) != 0:
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'in use')
pool_id = self.query_pool_id()
# remove cpus from pool
cpus = []
for pool_rec in xc.cpupool_getinfo():
if pool_rec['cpupool'] == pool_id:
cpus = pool_rec['cpulist']
for cpu_number in cpus:
xc.cpupool_removecpu(pool_id, cpu_number)
xc.cpupool_destroy(pool_id)
# update XenStore
xs_path = XS_POOLROOT + "%s/" % pool_id
xstransact.Remove(xs_path)
finally:
self.pool_lock.release()
def add_host_CPU_live(self, cpu_ref):
""" Add cpu to pool, if it is currently not assigned to a pool.
@param cpu_ref: reference of host_cpu instance to add
@type cpu_ref: str
"""
if not self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'deactivated')
node = XendNode.instance()
number = node.get_host_cpu_field(cpu_ref, 'number')
self.pool_lock.acquire()
try:
pool_id = self.query_pool_id()
other_pool_ref = self.get_cpu_pool_by_cpu_ref(cpu_ref)
if len(other_pool_ref) != 0:
raise PoolError(XEND_ERROR_INVALID_CPU,
'cpu already assigned to pool "%s"' % other_pool_ref[0])
xc.cpupool_addcpu(pool_id, number)
finally:
self.pool_lock.release()
if number not in self.proposed_cpus:
self.proposed_cpus.append(number)
self._update_ncpu(pool_id)
if self._managed:
XendNode.instance().save_cpu_pools()
def remove_host_CPU_live(self, cpu_ref):
""" Remove cpu from pool.
After successfull call, the cpu is free.
Remove of the last cpu of the pool is rejected.
@param cpu_ref: reference of host_cpu instance to remove
@type cpu_ref: str
"""
if not self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'deactivated')
node = XendNode.instance()
number = node.get_host_cpu_field(cpu_ref, 'number')
self.pool_lock.acquire()
try:
pool_id = self.query_pool_id()
pool_rec = {}
for pool in xc.cpupool_getinfo():
if pool['cpupool'] == pool_id:
pool_rec = pool
break
if number in pool_rec['cpulist']:
if len(pool_rec['cpulist']) < 2 and pool_rec['n_dom'] > 0:
raise PoolError(XEND_ERROR_LAST_CPU_NOT_REM,
'could not remove last cpu')
xc.cpupool_removecpu(pool_id, number)
else:
raise PoolError(XEND_ERROR_INVALID_CPU,
'CPU not assigned to pool')
finally:
self.pool_lock.release()
if number in self.proposed_cpus:
self.proposed_cpus.remove(number)
self._update_ncpu(pool_id)
if self._managed:
XendNode.instance().save_cpu_pools()
def add_to_proposed_CPUs(self, cpu):
if self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'activated')
_cpu = int(cpu)
if _cpu not in self.proposed_cpus:
self.proposed_cpus.append(_cpu)
self.proposed_cpus.sort()
if self._managed:
XendNode.instance().save_cpu_pools()
def remove_from_proposed_CPUs(self, cpu):
if self.get_activated():
raise PoolError(XEND_ERROR_BAD_POOL_STATE, 'activated')
_cpu = int(cpu)
if _cpu in self.proposed_cpus:
self.proposed_cpus.remove(_cpu)
if self._managed:
XendNode.instance().save_cpu_pools()
def add_to_other_config(self, key, value):
self.other_config[key] = value
if self._managed:
XendNode.instance().save_cpu_pools()
def remove_from_other_config(self, key):
if key in self.other_config:
del self.other_config[key]
if self._managed:
XendNode.instance().save_cpu_pools()
#
# Legacy RPC calls
#
def pool_new(cls, config):
try:
record = sxp2map(config)
if record.has_key('proposed_CPUs') and \
not isinstance(record['proposed_CPUs'], types.ListType):
record['proposed_CPUs'] = [record['proposed_CPUs']]
new_uuid = cls.create(record)
except XendAPIError, ex:
raise VmError(ex.get_api_error())
return new_uuid
def pool_create(cls, config):
try:
record = sxp2map(config)
if record.has_key('proposed_CPUs') and \
not isinstance(record['proposed_CPUs'], types.ListType):
record['proposed_CPUs'] = [record['proposed_CPUs']]
new_uuid = genuuid.createString()
pool = XendCPUPool(record, new_uuid, False)
pool.activate()
except XendAPIError, ex:
raise VmError(ex.get_api_error())
def pool_start(cls, poolname):
pool = cls.lookup_pool(poolname)
if not pool:
raise VmError('unknown pool %s' % poolname)
try:
pool.activate()
except XendAPIError, ex:
raise VmError(ex.get_api_error())
def pool_list(cls, names):
sxprs = []
try:
node = XendNode.instance()
xd = XendDomain.instance()
pools = cls.get_all_records()
for (pool_uuid, pool_vals) in pools.items():
if pool_vals['name_label'] in names or len(names) == 0:
# conv host_cpu refs to cpu number
cpus = [ node.get_host_cpu_field(cpu_ref, 'number')
for cpu_ref in pool_vals['host_CPUs'] ]
cpus.sort()
pool_vals['host_CPU_numbers'] = cpus
# query VMs names. Take in account, that a VM
# returned by get_all_records could be destroy, now
vm_names = [ vm.getName()
for vm in map(xd.get_vm_by_uuid,
pool_vals['started_VMs'])
if vm ]
pool_vals['started_VM_names'] = vm_names
pool_vals['auto_power_on'] = int(pool_vals['auto_power_on'])
sxprs += [[pool_uuid] + map2sxp(pool_vals)]
except XendAPIError, ex:
raise VmError(ex.get_api_error())
return sxprs
def pool_destroy(cls, poolname):
pool = cls.lookup_pool(poolname)
if not pool:
raise VmError('unknown pool %s' % poolname)
try:
pool.deactivate()
if not pool.is_managed():
pool.destroy()
except XendAPIError, ex:
raise VmError(ex.get_api_error())
def pool_delete(cls, poolname):
pool = cls.lookup_pool(poolname)
if not pool:
raise VmError('unknown pool %s' % poolname)
try:
pool.destroy()
except XendAPIError, ex:
raise VmError(ex.get_api_error())
def pool_cpu_add(cls, poolname, cpu):
pool = cls.lookup_pool(poolname)
if not pool:
raise VmError('unknown pool %s' % poolname)
try:
cpu_ref = cls._cpu_number_to_ref(int(cpu))
if cpu_ref:
pool.add_host_CPU_live(cpu_ref)
else:
raise PoolError(XEND_ERROR_INVALID_CPU,
'CPU unknown')
except XendAPIError, ex:
raise VmError(ex.get_api_error())
def pool_cpu_remove(cls, poolname, cpu):
pool = cls.lookup_pool(poolname)
if not pool:
raise VmError('unknown pool %s' % poolname)
try:
cpu_ref = cls._cpu_number_to_ref(int(cpu))
if cpu_ref:
pool.remove_host_CPU_live(cpu_ref)
else:
raise PoolError(XEND_ERROR_INVALID_CPU,
'CPU unknown')
except XendAPIError, ex:
raise VmError(ex.get_api_error())
def pool_migrate(cls, domname, poolname):
dom = XendDomain.instance()
pool = cls.lookup_pool(poolname)
if not pool:
raise VmError('unknown pool %s' % poolname)
dominfo = dom.domain_lookup_nr(domname)
if not dominfo:
raise VmError('unknown domain %s' % domname)
domid = dominfo.getDomid()
if domid is not None:
if domid == 0:
raise VmError('could not move Domain-0')
try:
cls.move_domain(pool.get_uuid(), domid)
except Exception, ex:
raise VmError('could not move domain')
dominfo.info['pool_name'] = poolname
dom.managed_config_save(dominfo)
pool_new = classmethod(pool_new)
pool_create = classmethod(pool_create)
pool_start = classmethod(pool_start)
pool_list = classmethod(pool_list)
pool_destroy = classmethod(pool_destroy)
pool_delete = classmethod(pool_delete)
pool_cpu_add = classmethod(pool_cpu_add)
pool_cpu_remove = classmethod(pool_cpu_remove)
pool_migrate = classmethod(pool_migrate)
#
# methods
#
def is_managed(self):
""" Check, if pool is managed.
@return: True, if managed
@rtype: bool
"""
return self._managed
def query_pool_id(self):
""" Get corresponding pool-id of pool instance from XenStore.
@return: pool id or None
@rytpe: int
"""
self.pool_lock.acquire()
try:
for pool_id in xstransact.List(XS_POOLROOT):
uuid = xstransact.Read(XS_POOLROOT + "%s/" % pool_id, 'uuid')
if uuid == self.get_uuid():
return int(pool_id)
finally:
self.pool_lock.release()
return None
def update_XS(self, pool_id):
""" Write (or update) data in xenstore taken from instance.
@param pool_id: Pool id to build path to pool data in xenstore
@type pool_id: int
"""
self.pool_lock.acquire()
try:
xs_path = XS_POOLROOT + "%s/" % pool_id
xs_entries = { 'uuid' : self.get_uuid(),
'name' : self.name_label,
'description' : self.name_description
}
xstransact.Mkdir(xs_path)
xstransact.Mkdir(xs_path, 'other_config')
xstransact.Write(xs_path, xs_entries)
xstransact.Write('%s%s' % (xs_path, 'other_config'),
self.other_config)
finally:
self.pool_lock.release()
def _update_ncpu(self, pool_id):
for pool_rec in xc.cpupool_getinfo():
if pool_rec['cpupool'] == pool_id:
self.ncpu = len(pool_rec['cpulist'])
def _checkName(self, name):
""" Check if a pool name is valid. Valid names contain alphabetic
characters, digits, or characters in '_-.:/+'.
The same name cannot be used for more than one pool at the same
time.
@param name: name
@type name: str
@raise: PoolError if invalid
"""
if name is None or name == '':
raise PoolError(XEND_ERROR_POOL_PARAM, 'Missing Pool Name')
if not re.search(r'^[A-Za-z0-9_\-\.\:\/\+]+$', name):
raise PoolError(XEND_ERROR_POOL_PARAM, 'Invalid Pool Name')
pool = self.lookup_pool(name)
if pool and pool.get_uuid() != self.get_uuid():
raise PoolError(XEND_ERROR_POOL_PARAM,
'Pool name "%s" already exists' % name)
#
# class methods
#
def recreate_active_pools(cls):
""" Read active pool config from hypervisor and create pool instances.
- Query pool ids and assigned CPUs from hypervisor.
- Query additional information for any pool from xenstore.
If an entry for a pool id is missing in xenstore, it will be
recreated with a new uuid and generic name (this is an error case)
- Create an XendCPUPool instance for any pool id
Function have to be called after recreation of managed pools.
"""
log.debug('recreate_active_pools')
for pool_rec in xc.cpupool_getinfo():
pool = pool_rec['cpupool']
# read pool data from xenstore
path = XS_POOLROOT + "%s/" % pool
uuid = xstransact.Read(path, 'uuid')
if not uuid:
# xenstore entry missing / invaild; create entry with new uuid
uuid = genuuid.createString()
name = "Pool-%s" % pool
try:
inst = XendCPUPool( { 'name_label' : name }, uuid, False )
inst.update_XS(pool)
except PoolError, ex:
# log error and skip domain
log.error('cannot recreate pool %s; skipping (reason: %s)' \
% (name, ex))
else:
(name, descr) = xstransact.Read(path, 'name', 'description')
other_config = {}
for key in xstransact.List(path + 'other_config'):
other_config[key] = xstransact.Read(
path + 'other_config/%s' % key)
# check existance of pool instance
inst = XendAPIStore.get(uuid, cls.getClass())
if inst:
# update attributes of existing instance
inst.name_label = name
inst.name_description = descr
inst.other_config = other_config
else:
# recreate instance
try:
inst = XendCPUPool(
{ 'name_label' : name,
'name_description' : descr,
'other_config' : other_config,
'proposed_CPUs' : pool_rec['cpulist'],
'ncpu' : len(pool_rec['cpulist']),
},
uuid, False )
except PoolError, ex:
# log error and skip domain
log.error(
'cannot recreate pool %s; skipping (reason: %s)' \
% (name, ex))
recreate_active_pools = classmethod(recreate_active_pools)
def recreate(cls, record, current_uuid):
""" Recreate a pool instance while xend restart.
@param record: attributes of pool
@type record: dict
@param current_uuid: uuid of pool to create
@type current_uuid: str
"""
XendCPUPool(record, current_uuid)
recreate = classmethod(recreate)
def autostart_pools(cls):
""" Start managed pools that are marked as autostart pools.
Function is called after recreation of managed domains while
xend restart.
"""
cls.pool_lock.acquire()
try:
for inst in XendAPIStore.get_all(cls.getClass()):
if inst.is_managed() and inst.auto_power_on and \
inst.query_pool_id() == None:
inst.activate()
finally:
cls.pool_lock.release()
autostart_pools = classmethod(autostart_pools)
def move_domain(cls, pool_ref, domid):
cls.pool_lock.acquire()
try:
pool = XendAPIStore.get(pool_ref, cls.getClass())
pool_id = pool.query_pool_id()
xc.cpupool_movedomain(pool_id, domid)
finally:
cls.pool_lock.release()
move_domain = classmethod(move_domain)
def query_pool_ref(cls, pool_id):
""" Get pool ref by pool id.
Take the ref from xenstore.
@param pool_id:
@type pool_id: int
@return: ref
@rtype: str
"""
uuid = xstransact.Read(XS_POOLROOT + "%s/" % pool_id, 'uuid')
if uuid:
return [uuid]
else:
return []
query_pool_ref = classmethod(query_pool_ref)
def lookup_pool(cls, id_or_name):
""" Search XendCPUPool instance with given id_or_name.
@param id_or_name: pool id or pool nameto search
@type id_or_name: [int, str]
@return: instane or None if not found
@rtype: XendCPUPool
"""
pool_uuid = None
try:
pool_id = int(id_or_name)
# pool id given ?
pool_uuid = cls.query_pool_ref(pool_id)
if not pool_uuid:
# not found -> search name
pool_uuid = cls.get_by_name_label(id_or_name)
except ValueError:
# pool name given
pool_uuid = cls.get_by_name_label(id_or_name)
if len(pool_uuid) > 0:
return XendAPIStore.get(pool_uuid[0], cls.getClass())
else:
return None
lookup_pool = classmethod(lookup_pool)
def _cpu_number_to_ref(cls, number):
node = XendNode.instance()
for cpu_ref in node.get_host_cpu_refs():
if node.get_host_cpu_field(cpu_ref, 'number') == number:
return cpu_ref
return None
_cpu_number_to_ref = classmethod(_cpu_number_to_ref)
def unbound_cpus(cls):
""" Build list containing the numbers of all cpus not bound to a pool.
Info is taken from Hypervisor.
@return: list of cpu numbers
@rytpe: list of int
"""
return xc.cpupool_freeinfo()
unbound_cpus = classmethod(unbound_cpus)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.