def _configure_core_cgroups(service_name): """Configure service specific cgroups.""" group = os.path.join('treadmill/core', service_name) # create group directory for subsystem in ['memory', 'cpu', 'cpuacct', 'blkio']: _LOGGER.info('creating and joining: %s/%s', subsystem, group) cgutils.create(subsystem, group) cgroups.join(subsystem, group) # set memory usage limits memlimits = [ 'memory.limit_in_bytes', 'memory.memsw.limit_in_bytes', 'memory.soft_limit_in_bytes' ] for limit in memlimits: parent_limit = cgroups.get_value('memory', 'treadmill/core', limit) _LOGGER.info('setting %s: %s', limit, parent_limit) cgroups.set_value('memory', group, limit, parent_limit) # set cpu share limits cpulimits = ['cpu.shares'] for limit in cpulimits: parent_limit = cgroups.get_value('cpu', 'treadmill/core', limit) _LOGGER.info('setting %s: %s', limit, parent_limit) cgroups.set_value('cpu', group, limit, parent_limit)
def test_get_value(self): """Test cgroup value fetching""" value = cgroups.get_value('memory', 'foo', 'memory,usage_in_bytes') self.assertEqual(value, 2) value = cgroups.get_value('memory', 'foo', 'memory,usage_in_bytes') self.assertEqual(value, 1) value = cgroups.get_value('memory', 'foo', 'memory,usage_in_bytes') self.assertEqual(value, 0) value = cgroups.get_value('memory', 'foo', 'memory,usage_in_bytes') self.assertEqual(value, 0)
def reset_memory_limit_in_bytes(cgroup_prefix): """Recalculate the hard memory limits. If any app uses more than the value we are trying to resize to, it will be expunged. :returns: List of unique application names to expunge from the system. """ total_soft_mem = float(total_soft_memory_limits(cgroup_prefix)) apps_group = apps_group_name(cgroup_prefix) total_hard_mem = cgroups.get_value('memory', apps_group, 'memory.limit_in_bytes') basepath = cgroups.makepath('memory', apps_group) _LOGGER.info('total_soft_mem: %r, total_hard_mem: %r', total_soft_mem, total_hard_mem) expunged = [] for f in os.listdir(basepath): if not os.path.isdir(os.path.join(basepath, f)): continue cgrp = os.path.join(apps_group, f) soft_limit = float( cgroups.get_value('memory', cgrp, 'memory.soft_limit_in_bytes')) percentage_of_allocated = soft_limit / total_soft_mem hard_limit = int(percentage_of_allocated * total_hard_mem) _LOGGER.info('%s: soft_limit %r, pcnt: %r, hard_limit: %r', cgrp, soft_limit, percentage_of_allocated, hard_limit) if hard_limit < soft_limit: hard_limit = int(soft_limit) _LOGGER.debug('Setting cgroup %r hardlimit to %r', cgrp, hard_limit) try: set_memory_hardlimit(cgrp, hard_limit) except TreadmillCgroupError: # Unable to resize group, add it to the expunged groups. expunged.append(f) return expunged
def _configure_service_cgroups(cgroup, root_cgroup): """Configure service specific cgroups.""" from treadmill import cgroups from treadmill import cgutils if cgroup == '.': cgroup = os.path.basename(os.path.realpath('.')) if os.path.isabs(cgroup): group = os.path.join(root_cgroup, cgroup.lstrip('/')) else: group = os.path.join( cgutils.core_group_name(root_cgroup), cgroup ) parent = os.path.dirname(group) # create group directory for subsystem in ['memory', 'cpu', 'cpuacct', 'cpuset', 'blkio']: _LOGGER.info('creating : %s/%s', subsystem, group) cgutils.create(subsystem, group) # set memory usage limits memlimits = ['memory.limit_in_bytes', 'memory.memsw.limit_in_bytes', 'memory.soft_limit_in_bytes'] for limit in memlimits: parent_limit = cgroups.get_value('memory', parent, limit) _LOGGER.info('setting %s: %s', limit, parent_limit) cgroups.set_value('memory', group, limit, parent_limit) # set cpu share limits cpulimits = ['cpu.shares'] for limit in cpulimits: parent_limit = cgroups.get_value('cpu', parent, limit) _LOGGER.info('setting %s: %s', limit, parent_limit) cgroups.set_value('cpu', group, limit, parent_limit) # set cpuset cgroups.inherit_value('cpuset', group, 'cpuset.cpus') cgroups.inherit_value('cpuset', group, 'cpuset.mems') # join cgroup for subsystem in ['memory', 'cpu', 'cpuacct', 'cpuset', 'blkio']: _LOGGER.info('joining: %s/%s', subsystem, group) cgroups.join(subsystem, group)
def _transfer_processes(subsystem, fromgroup, togroup): """Do the transfer of processes""" pids = cgroups.get_value(subsystem, fromgroup, 'tasks') for pid in pids.strip().split('\n'): try: cgroups.set_value(subsystem, togroup, 'tasks', pid) except IOError as ioe: # pylint: disable=W0702 if ioe.errno not in [errno.EINVAL, errno.ESRCH]: raise
def cgrp_meminfo(cgrp, *pseudofiles): """Grab the cgrp mem limits""" if pseudofiles is None or not pseudofiles: pseudofiles = _MEMORY_TYPE metrics = {} for pseudofile in pseudofiles: data = cgroups.get_value('memory', cgrp, pseudofile) # remove memory. prefix metrics[pseudofile] = data return metrics
def get_cpu_shares(cgrp): """Get cpu shares""" return cgroups.get_value('cpu', cgrp, 'cpu.shares')
def cpu_usage(cgrp): """Return (in nanoseconds) the length of time on the cpu""" nanosecs = cgroups.get_value('cpuacct', cgrp, 'cpuacct.usage') return nanosecs
def get_memory_limit(cgrp): """Get memory size hard limit """ return cgroups.get_value('memory', cgrp, 'memory.limit_in_bytes')
def create_treadmill_cgroups(system_cpu_shares, treadmill_cpu_shares, treadmill_core_cpu_shares, treadmill_apps_cpu_shares, treadmill_cpu_cores, treadmill_mem, treadmill_core_mem): """This is the core cgroup setup. Should be applied to a cleaned env.""" create('cpu', 'system') create('cpu', 'treadmill') create('cpu', 'treadmill/core') create('cpu', 'treadmill/apps') cgroups.set_value('cpu', 'treadmill', 'cpu.shares', treadmill_cpu_shares) cgroups.set_value('cpu', 'system', 'cpu.shares', system_cpu_shares) cgroups.set_value('cpu', 'treadmill/core', 'cpu.shares', treadmill_core_cpu_shares) cgroups.set_value('cpu', 'treadmill/apps', 'cpu.shares', treadmill_apps_cpu_shares) create('cpuacct', 'system') create('cpuacct', 'treadmill') create('cpuacct', 'treadmill/core') create('cpuacct', 'treadmill/apps') create('cpuset', 'system') create('cpuset', 'treadmill') mems = cgroups.get_value('cpuset', '', 'cpuset.mems') cgroups.set_value('cpuset', 'system', 'cpuset.mems', mems) cgroups.set_value('cpuset', 'treadmill', 'cpuset.mems', mems) cores_max = sysinfo.cpu_count() - 1 if treadmill_cpu_cores > cores_max: raise exc.TreadmillError('Not enough cpu cores.') if treadmill_cpu_cores > 0: cgroups.set_value('cpuset', 'treadmill', 'cpuset.cpus', '%d-%d' % (0, treadmill_cpu_cores - 1)) cgroups.set_value('cpuset', 'system', 'cpuset.cpus', '%d-%d' % (treadmill_cpu_cores, cores_max)) else: cgroups.set_value('cpuset', 'treadmill', 'cpuset.cpus', '%d-%d' % (0, cores_max)) cgroups.set_value('cpuset', 'system', 'cpuset.cpus', '%d-%d' % (0, cores_max)) create('memory', 'system') create('memory', 'treadmill') if cgroups.get_value('memory', 'treadmill', 'memory.use_hierarchy') != 1: cgroups.set_value('memory', 'treadmill', 'memory.use_hierarchy', '1') set_memory_hardlimit('treadmill', treadmill_mem) oom_value = 'oom_kill_disable 0\nunder_oom 0\n' if cgroups.get_data('memory', 'treadmill', 'memory.oom_control') != oom_value: cgroups.set_value('memory', 'treadmill', 'memory.oom_control', '0') create('memory', 'treadmill/core') create('memory', 'treadmill/apps') set_memory_hardlimit('treadmill/core', treadmill_core_mem) cgroups.set_value('memory', 'treadmill/core', 'memory.soft_limit_in_bytes', treadmill_core_mem) # It is possible to use qualifiers in the input, for calculation of the # difference, get memory limits in bytes as defined in cgroup. total_mem_bytes = cgroups.get_value('memory', 'treadmill', 'memory.limit_in_bytes') core_mem_bytes = cgroups.get_value('memory', 'treadmill/core', 'memory.limit_in_bytes') apps_mem_bytes = (total_mem_bytes - core_mem_bytes) set_memory_hardlimit('treadmill/apps', apps_mem_bytes)