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 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 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 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 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 _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)
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 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 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 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 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 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_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()