Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
    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}
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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