예제 #1
0
    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()
예제 #2
0
    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()
예제 #3
0
 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()
예제 #4
0
    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
예제 #5
0
 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()
예제 #6
0
    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)
예제 #7
0
    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()
예제 #8
0
    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()
예제 #9
0
 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()
예제 #10
0
 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())
예제 #11
0
    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()
예제 #12
0
 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()
예제 #13
0
 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()