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 on_create_request(self, rsrc_id, rsrc_data): instance_id = rsrc_id memory_limit = rsrc_data['memory'] cpu_limit = rsrc_data['cpu'] cgrp = os.path.join('treadmill', 'apps', instance_id) with lc.LogContext(_LOGGER, rsrc_id, adapter_cls=lc.ContainerAdapter) as log: log.info('Creating cgroups: %s:%s', self.SUBSYSTEMS, cgrp) for subsystem in self.SUBSYSTEMS: cgutils.create(subsystem, cgrp) # blkio settings # cgroups.set_value('blkio', cgrp, 'blkio.weight', 100) # memory settings # self._register_oom_handler(cgrp, instance_id) cgroups.set_value('memory', cgrp, 'memory.soft_limit_in_bytes', memory_limit) # TODO: set hardlimit to app.memory and comment the # reset_memory block until proper solution for # cgroup race condition is implemented. cgutils.set_memory_hardlimit(cgrp, memory_limit) # expunged = cgutils.reset_memory_limit_in_bytes() # for expunged_uniq_name in expunged: # exp_app_dir = os.path.join(tm_env.apps_dir, # expunged_uniq_name) # with open(os.path.join(exp_app_dir, # 'services', 'finished'), 'w') as f: # f.write('oom') # exp_cgrp = os.path.join('treadmill', 'apps', # expunged_uniq_name) # cgutils.kill_apps_in_cgroup('memory', exp_cgrp, # delete_cgrp=False) # cpu settings # # Calculate the value of cpu shares for the app. # # [treadmill/apps/cpu.shares] = <total bogomips allocated to TM> # # [treadmill/apps/<app>/cpu.shares] = app.cpu * BMIPS_PER_CPU # app_cpu_pcnt = utils.cpu_units(cpu_limit) / 100. app_bogomips = app_cpu_pcnt * sysinfo.BMIPS_PER_CPU app_cpu_shares = int(app_bogomips) log.info('created in cpu:%s with %s shares', cgrp, app_cpu_shares) cgroups.set_cpu_shares(cgrp, app_cpu_shares) return {subsystem: cgrp for subsystem in self.SUBSYSTEMS}
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 cgexec(into, subcommand): """execs command into given cgroup(s). """ cgrps = [cgrp.split(':') for cgrp in into] for (subsystem, path) in cgrps: pathplus = path.split('=') if len(pathplus) == 2: group = os.path.dirname(pathplus[0]) pseudofile = os.path.basename(pathplus[0]) value = pathplus[1] cgroups.set_value(subsystem, group, pseudofile, value) else: cgutils.create(subsystem, path) cgroups.join(subsystem, path) if subcommand: execargs = list(subcommand) utils.sane_execvp(execargs[0], execargs)
def on_create_request(self, rsrc_id, rsrc_data): app_unique_name = rsrc_id size = rsrc_data['size'] read_bps = self._default_read_bps write_bps = self._default_write_bps read_iops = self._default_read_iops write_iops = self._default_write_iops with lc.LogContext(_LOGGER, rsrc_id, adapter_cls=lc.ContainerAdapter) as log: log.info('Processing request') size_in_bytes = utils.size_to_bytes(size) uniqueid = _uniqueid(app_unique_name) # Create the logical volume existing_volume = uniqueid in self._volumes if not existing_volume: needed = math.ceil(size_in_bytes / self._vg_status['extent_size']) if needed > self._vg_status['extent_free']: # If we do not have enough space, delay the creation until # another volume is deleted. log.info( 'Delaying request %r until %d extents are free.' ' Current volumes: %r', rsrc_id, needed, self._volumes) self._pending.append(rsrc_id) return None lvm.lvcreate( volume=uniqueid, group=self._vg_name, size_in_bytes=size_in_bytes, ) # We just created a volume, refresh cached status from LVM self._vg_status = localdiskutils.refresh_vg_status( self._vg_name) lv_info = lvm.lvdisplay(volume=uniqueid, group=self._vg_name) # Configure block device using cgroups (this is idempotent) # FIXME(boysson): The unique id <-> cgroup relation should be # captured in the cgroup module. cgrp = os.path.join('treadmill', 'apps', app_unique_name) cgutils.create('blkio', cgrp) major, minor = lv_info['dev_major'], lv_info['dev_minor'] cgroups.set_value( 'blkio', cgrp, 'blkio.throttle.write_bps_device', '{major}:{minor} {bps}'.format( major=major, minor=minor, bps=utils.size_to_bytes(write_bps), )) cgroups.set_value( 'blkio', cgrp, 'blkio.throttle.read_bps_device', '{major}:{minor} {bps}'.format( major=major, minor=minor, bps=utils.size_to_bytes(read_bps), )) cgroups.set_value( 'blkio', cgrp, 'blkio.throttle.write_iops_device', '{major}:{minor} {iops}'.format(major=major, minor=minor, iops=write_iops)) cgroups.set_value( 'blkio', cgrp, 'blkio.throttle.read_iops_device', '{major}:{minor} {iops}'.format(major=major, minor=minor, iops=read_iops)) volume_data = { k: lv_info[k] for k in ['name', 'block_dev', 'dev_major', 'dev_minor', 'extent_size'] } # Record existence of the volume. self._volumes[lv_info['name']] = volume_data return volume_data