Example #1
0
def ulimit(command, mem_limit=None, time_limit=None, **kwargs):
    # This could be nicely replaced with preexec_fn + resource.setrlimit, but
    # it does not work: RLIMIT_VMEM is usually not available (and we must take
    # into consideration that python has to fit in it before execve)
    command = isinstance(command, list) and command or [command]
    if mem_limit:
        command = ['ulimit', '-v', str(mem_limit), noquote('&&')] + command
        # Unlimited stack
        command = ['ulimit', '-Ss', 'unlimited', noquote('&&')] + command

    if time_limit:
        command = ['ulimit', '-t',
                   str(ceil_ms2s(time_limit)),
                   noquote('&&')] + command

    return command
Example #2
0
    def _execute(self, command, **kwargs):
        env = kwargs.get('env')
        env.update({
            'MEM_LIMIT': kwargs['mem_limit'] or 64 * 2**10,
            'TIME_LIMIT': kwargs['time_limit'] or 30000,
            'OUT_LIMIT': kwargs['output_limit'] or 50 * 2**20,
        })

        if kwargs['real_time_limit']:
            env['HARD_LIMIT'] = 1 + ceil_ms2s(kwargs['real_time_limit'])
        elif kwargs['time_limit'] and kwargs['real_time_limit'] is None:
            env['HARD_LIMIT'] = 1 + ceil_ms2s(64 * kwargs['time_limit'])

        if 'HARD_LIMIT' in env:
            # Limiting outside supervisor
            kwargs['real_time_limit'] = 2 * s2ms(env['HARD_LIMIT'])

        ignore_errors = kwargs.pop('ignore_errors')
        extra_ignore_errors = kwargs.pop('extra_ignore_errors')
        renv = {}
        try:
            result_file = tempfile.NamedTemporaryFile(dir=tempcwd())
            kwargs['ignore_errors'] = True
            renv = execute_command(command + [noquote('3>'), result_file.name],
                                   **kwargs)

            if 'real_time_killed' in renv:
                raise ExecError('Supervisor exceeded realtime limit')
            elif renv['return_code'] and renv[
                    'return_code'] not in extra_ignore_errors:
                raise ExecError('Supervisor returned code %s' %
                                renv['return_code'])

            result_file.seek(0)
            status_line = result_file.readline().strip().split()[1:]
            renv['result_string'] = result_file.readline().strip()
            result_file.close()
            for num, key in enumerate(('result_code', 'time_used', None,
                                       'mem_used', 'num_syscalls')):
                if key:
                    renv[key] = int(status_line[num])

            result_code = self._supervisor_result_to_code(renv['result_code'])

        except Exception as e:
            logger.error('SupervisedExecutor error: %s',
                         traceback.format_exc())
            logger.error(
                'SupervisedExecutor error dirlist: %s: %s',
                tempcwd(),
                str(os.listdir(tempcwd())),
            )

            result_code = 'SE'
            for i in ('time_used', 'mem_used', 'num_syscalls'):
                renv.setdefault(i, 0)
            renv['result_string'] = str(e)

        renv['result_code'] = result_code

        if (result_code != 'OK' and not ignore_errors
                and not (result_code != 'RV'
                         and renv['return_code'] in extra_ignore_errors)):
            raise ExecError('Failed to execute command: %s. Reason: %s' %
                            (command, renv['result_string']))
        return renv