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 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 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))
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))
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 []
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 number_of_pools(cls): return len(xc.cpupool_getinfo())
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'])