def on_delete_request(self, rsrc_id): instance_id = rsrc_id apps_group = cgutils.apps_group_name(self._cgroup_prefix) cgrp = os.path.join(apps_group, instance_id) with lc.LogContext(_LOGGER, rsrc_id, adapter_cls=lc.ContainerAdapter) as log: self._unregister_oom_handler(cgrp) log.info('Deleting cgroups: %s:%s', self.SUBSYSTEMS, cgrp) for subsystem in self.SUBSYSTEMS: cgutils.delete(subsystem, cgrp) # Recalculate the cgroup hard limits on remaining apps # # TODO: commented out until proper fix implemented. # # 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) return True
def collect_cgroup(archive, cgroup_prefix): """Get host treadmill cgroups inforamation.""" core_group = cgutils.core_group_name(cgroup_prefix) _add_glob( archive, os.path.join(cgroups.CGROOT, '*', core_group, '*') ) apps_group = cgutils.apps_group_name(cgroup_prefix) _add_glob( archive, os.path.join(cgroups.CGROOT, '*', apps_group, '*', '*') )
def read_psmem_stats(appname, allpids, cgroup_prefix): """Reads per-proc memory details stats.""" apps_group = cgutils.apps_group_name(cgroup_prefix) cgrp = os.path.join(apps_group, appname) group_pids = set(cgutils.pids_in_cgroup('memory', cgrp)) # Intersection of all /proc pids (allpids) and pid in .../tasks will give # the set we are interested in. # # "tasks" contain thread pids that we want to filter out. meminfo = psmem.get_memory_usage(allpids & group_pids, use_pss=True) return meminfo
def on_delete_request(self, rsrc_id): instance_id = rsrc_id apps_group = cgutils.apps_group_name(self._cgroup_prefix) cgrp = os.path.join(apps_group, instance_id) with lc.LogContext(_LOGGER, rsrc_id, adapter_cls=lc.ContainerAdapter) as log: self._unregister_oom_handler(cgrp) log.info('Deleting cgroups: %s:%s', self.SUBSYSTEMS, cgrp) for subsystem in self.SUBSYSTEMS: cgutils.delete(subsystem, cgrp) return True
def on_create_request(self, rsrc_id, rsrc_data): instance_id = rsrc_id memory_limit = rsrc_data['memory'] cpu_limit = rsrc_data['cpu'] apps_group = cgutils.apps_group_name(self._cgroup_prefix) cgrp = os.path.join(apps_group, 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) cgutils.create(subsystem, os.path.join(cgrp, 'services')) # 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) cgutils.set_cpu_shares(cgrp, app_cpu_shares) log.info('Inherit parent cpuset.cpus for %s', cgrp) cgroups.inherit_value('cpuset', cgrp, 'cpuset.cpus') log.info('Inherit parent cpuset.mems for %s', cgrp) cgroups.inherit_value('cpuset', cgrp, 'cpuset.mems') return {subsystem: cgrp for subsystem in self.SUBSYSTEMS}
def psmem_cmd(fast, app, verbose, percent, root_cgroup): """Reports memory utilization details for given container. """ if app.find('#') == -1: raise click.BadParameter('Specify full instance name: xxx#nnn') app = app.replace('#', '-') cgroup = None apps_group = cgutils.apps_group_name(root_cgroup) apps = os.listdir(os.path.join(cgroups.CG_ROOT, 'memory', apps_group)) for entry in apps: if app in entry: cgroup = os.path.join(apps_group, entry) if not cgroup: raise click.BadParameter('Could not find corresponding cgroup') pids = cgutils.pids_in_cgroup('memory', cgroup) use_pss = not fast memusage = psmem.get_memory_usage(pids, verbose, use_pss=use_pss) total = sum([info['total'] for info in memusage]) def _readable(value): return utils.bytes_to_readable(value, power='B') def _percentage(value, total): return '{:.1%}'.format(value / total) to_format = ['private', 'shared', 'total'] for info in memusage: for key, val in info.items(): if key in to_format: if percent: info[key] = _percentage(val, total) else: info[key] = _readable(val) proc_table = PsmemProcPrettyFormatter() print(proc_table.format(memusage)) metric = metrics.read_memory_stats(cgroup) total_list = [] # Actual memory usage is without the disk cache total_list.append({ 'memory-type': 'usage', 'value': _readable(metric['memory.usage_in_bytes'] - metric['memory.stat']['cache']) }) total_list.append({ 'memory-type': '', 'value': _percentage(metric['memory.usage_in_bytes'], metric['memory.limit_in_bytes']) }) total_list.append({ 'memory-type': 'diskcache', 'value': _readable(metric['memory.stat']['cache']) }) total_list.append({ 'memory-type': 'softlimit', 'value': _readable(metric['memory.soft_limit_in_bytes']) }) total_list.append({ 'memory-type': 'hardlimit', 'value': _readable(metric['memory.limit_in_bytes']) }) total_table = PsmemTotalPrettyFormatter() print('') print(total_table.format(total_list))
def read_app(self, name): """Get treadmill app cgroup value.""" path = cgutils.apps_group_name(self._cgroup_prefix) (block_dev, _blkio_major_minor) = self._get_block_dev_version(name) return _read(path, name, block_dev=block_dev)