Configurando OS X / MacOS / BSD maxfile

3

Estou com problemas na minha máquina do OS X que posso rastrear até o número de arquivos abertos permitidos por processo. Se eu olhar para a opção maxfiles usando o comando launchctl ' limit (na minha máquina OS X El Cap)

$ launchctl limit
    cpu         unlimited      unlimited      
    filesize    unlimited      unlimited      
    data        unlimited      unlimited      
    stack       8388608        67104768       
    core        0              unlimited      
    rss         unlimited      unlimited      
    memlock     unlimited      unlimited      
    maxproc     709            1064           
    maxfiles    256            unlimited

Parece haver um limite flexível de 256 e um limite rígido de "ilimitado". Eu gostaria de alterar o limite flexível para algo como 2048 e deixar o limite rígido intocado. Quando olho para os argumentos de limit

$ launchctl help limit
Usage: launchctl limit [<limit-name> [<both-limits> | <soft-limit> <hard-limit>]

Parece que posso definir os dois limites para a mesma coisa, ou definir um valor para soft e hard. No entanto, se eu tentar definir um limite rígido ilimitado.

$ sudo launchctl limit maxfiles 2048 unlimited

Acabo com o curioso valor de 10240

$ launchctl limit
    cpu         unlimited      unlimited      
    filesize    unlimited      unlimited      
    data        unlimited      unlimited      
    stack       8388608        67104768       
    core        0              unlimited      
    rss         unlimited      unlimited      
    memlock     unlimited      unlimited      
    maxproc     709            1064           
    maxfiles    2048           10240          

O que está acontecendo aqui? É possível definir um valor ilimitado? Se não, isso é uma limitação do comando launchctl limit , ou algo no nível do sistema? Se mais tarde, quais são todos os valores iniciais de unlimited reporting? Ou esta Apple é a Apple?

Para pontos de bônus - alguém sabe por que este limite é definido tão baixo em primeiro lugar?

    
por Alan Storm 11.03.2017 / 19:25

1 resposta

2

Isso é algo que o XNU, o FreeBSD, o TrueOS e o OpenBSD têm em comum. Não há como unlimitar os limites rígidos e suaves dos descritores de arquivos abertos. Os vários kernels do sistema operacional, apesar de diferirem entre si sobre o comportamento exato, simplesmente não permitem definir os limites de RLIMIT_NOFILES para RLIM_INFINITY com a função setrlimit() .

Isso é totalmente não documentado em todos eles.

O comportamento não documentado é que tanto o limite flexível quanto o limite rígido para o segmento de dados, o segmento de pilha, o número máximo de processos por usuário e o número máximo de descritores de arquivos abertos são todos limitados pelos valores de sysctl de variáveis do kernel. Os detalhes, como exatamente qual variável do kernel é o limite para cada limite, variam de sistema operacional para sistema operacional.

  • No XNU, os processos privilegiados não podem definir os limites dos descritores de arquivos abertos superiores ao valor da variável kern.maxfiles kernel; e processos não privilegiados não podem definir os limites de descritores de arquivos abertos superiores ao valor da variável de kernel kern.maxfilesperproc . Aqui está o código.
  • No FreeBSD e no TrueOS, os processos não podem definir os limites dos descritores de arquivos abertos superiores ao valor da variável do kernel kern.maxfilesperproc . Aqui está o código.
  • No OpenBSD, os processos não podem definir os limites dos descritores de arquivos abertos superiores ao valor da variável kern.maxfiles kernel. Aqui está o código.

Em todos eles, a tampa é silenciosa. A chamada setrlimit() não retorna um erro. Simples e silenciosamente, define um valor mais baixo para o limite do que o valor que o programa solicitou. (XNU tem um "modo POSIX" no qual ele gera um erro se tentar aumentar o limite soft além do limite. Mas definir o limite hard , como você está fazendo é limitado silenciosamente como nos outros sistemas operacionais.) Se um programa tentar desativar a imposição de um limite, nesses sistemas operacionais, o que acontece é que o limite continua a ser imposto, no nível do valor limite.

Estritamente falando, isso é uma contravenção da Especificação Unix Única, que requer um comportamento específico de RLIM_INFINITY e não faz provisão para silenciosamente não fornecer esse comportamento sem um retorno de erro:

Specifying RLIM_INFINITY as any resource limit value on a successful call to setrlimit() inhibits enforcement of that resource limit.

O comando launchctl limit , como diz o manual, é simplesmente uma maneira de instruir o processo launchd a chamar setrlimit() para definir seus próprios limites de recursos de processo. Então, o que você está vendo é o launchd process começando com um limite rígido ilimitado no número de descritores de arquivos abertos e, em seguida, ganhando um limite finito, o valor de kern.maxfilesperproc , na primeira tentativa para definir o limite do descritor de arquivo aberto para ilimitado.

(O mesmo acontece no FreeBSD / TrueOS, com o limite rígido dos descritores de arquivos abertos que o processo # 1 começa sendo alto e o programa # 1 explicitamente redefinindo o limite rígido para um valor finito menor).

(Na verdade, existe um bug bastante desagradável no Terminal GNOME, onde ele não consegue iniciar nenhuma sessão de terminal, que pode ser disparado nesses sistemas operacionais se os descritores de arquivos abertos limitam que o processo do Terminal GNOME inicialmente herda de seus terminais. pai é maior do que o valor atual de kern.maxfiles / kern.maxfilesperproc . Os autores do Terminal do GNOME decidiram que uma falha ao definir o limite rígido para o mesmo valor que foi inicialmente lido é um erro fatal , sem levar em conta o fato de que o GNOME Terminal terá, entretanto, acionado o XNU Comportamento de BSD que silenciosamente baixa o limite rígido, fazendo com que o código acabe tentando aumentar , o que é motivo para falha.)

10240 é simplesmente o valor inicial compilado da variável do kernel kern.maxfilesperproc no XNU. Não é, contudo, bastante tão simples. No bootstrap do sistema, quando em "modo de desempenho do servidor", o XNU inicializará essa variável em vez de 75.000 vezes o valor de escala .

    
por 12.03.2017 / 00:08

Tags