Limitação do recurso (tempo e memória da CPU) e encerramento de um processo após violação no Linux

3

O problema:

Dado um processo, limite os recursos que ele e seus processos-filhos podem usar. Ou seja defina o tempo de CPU e as cotas de memória virtual. Quando o grupo de processos exceder um dos limites, termine-o, caso contrário, imprima a quantidade de tempo de CPU e memória virtual usada.

O caso de uso concreto:

Basicamente, devo executar alguns binários, que esperam a entrada de um arquivo, mas devo garantir que o processo de execução deles seja estritamente limitado. Por exemplo, o binário não deve alocar mais de 256 MB de memória e deve ser executado por menos de 0,5 segundos. Espero que isso faça sentido agora. No entanto, eu preciso de informações sobre a quantidade de memória e CPU usada.

O que tentei:

  1. Por alguns dias, tenho lidado com este script perl , que é a melhor solução que encontrei até agora. Infelizmente sua memória é buggy e não é muito precisa. Também há um post de autor oficial sobre este script aqui
  2. Eu tentei usar as ferramentas /usr/bin/timeout e timeout do Linux, o que naturalmente me ajudou com a cota de tempo da CPU, mas não com o término do processo devido à violação do limite de memória virtual.
  3. O uso de ulimit também foi tentado, mas, como eu disse anteriormente, eu preciso não apenas de limitação, mas também de feedback para o consumo de recursos.

A pergunta:

O que pode me ajudar a resolver esse problema? Eu não me importo com o que é, contanto que possa ajudar.

Edit 1: Adicionadas informações para o caso de uso concreto para melhor compreensão do problema.

    
por 0x450 15.07.2015 / 12:44

1 resposta

1

O setrlimit (2) syscall é relevante para limitar recursos (tempo de CPU - número inteiro de segundos, então pelo menos 1 segundo com RLIMIT_CPU , tamanho do arquivo com RLIMIT_FSIZE , espaço de endereçamento com RLIMIT_AS , etc ...). Você também pode configurar cotas de disco . O syscall wait4 (2) informa e dá feedback sobre o uso de alguns recursos. E proc (5) diz muito mais, e também getrusage(2) (você pode codificar um monitor que interrompa periodicamente todo o grupo de processos usando SIGSTOP , chamada getrusage ou consulta /proc/$PID/ , depois envie SIGCONT -para continuar- ou SIGTERM -para terminar-- para esse grupo de processos).

A ferramenta valgrind é muito útil no Linux para ajudar a encontrar vazamentos de memória. E o strace (1) também deve ser útil.

Se você puder recompilar o software defeituoso, você pode considerar as opções -fsanitize=address e -fsanitize=undefined e outras -fsanitize= ... para uma versão recente do GCC compilador.

Talvez você tenha algum processamento em lote . Procure por monitores de lote, ou simplesmente codifique sua própria coisa em C, Python, Ocaml, Perl, .... (que bifurca o comando e faz loop no monitoramento dele ...). Talvez você queira alguma contabilidade de processo (veja acct (5) & sa(8) ...)

Observe que "quantidade de memória usada" (um programa geralmente aloca com mmap & libera memória com munmap para o kernel durante a execução) e "Tempo de CPU" (consulte time(7) , pense em programas multi-threaded ...) são conceitos muito difusos.

Veja também PAM e configure as coisas em /etc/security/ ; talvez o inotify (7) também possa ser útil (mas provavelmente não).

Leia também Programação Avançada em Linux e syscalls (2)

    
por 15.07.2015 / 13:11