A implementação do Linux da variável de configuração do sistema ARG_MAX é diferente de outras variáveis do sistema e é compatível com POSIX?

4

No shell, conforme explicado nesta Q & A no contexto da expansão, dependendo do sistema, o comprimento máximo do argumento de um comando é inicialmente restringido pela configuração do kernel. O valor máximo é revelado em tempo de execução usando o comando getconf (veja também IEEE Std 1003.1, edição 2013 ):

# getconf ARG_MAX
2097152
vs. value found in limits.h on my setup:
#define ARG_MAX       131072    /* # bytes of args + environ for exec() */

De fato:

The sysconf() call supplies a value that corresponds to the conditions when the program was either compiled or executed, depending on the implementation; the system() call to getconf always supplies a value corresponding to conditions when the program is executed.

As páginas de manual fazem referência ao POSIX, desde o prólogo que alude ao manual do Programador POSIX , à descrição :

The value of each configuration variable shall be determined as if it were obtained by calling the function from which it is defined to be available by this volume of POSIX.1-2008 or by the System Interfaces volume of POSIX.1-2008 (see the OPERANDS section). The value shall reflect conditions in the current operating environment.

As variáveis básicas que podem ser consultadas aparecem na tabela para a especificação da função sysconf e há mais informações sobre os valores no limits.h documentação do cabeçalho:

{ARG_MAX}
    Maximum length of argument to the exec functions including environment data.
    Minimum Acceptable Value: {_POSIX_ARG_MAX}
...(nb you cannot be POSIX compliant under a certain value...)
{_POSIX_ARG_MAX}
    Maximum length of argument to the exec functions including environment data.
    Value: 4 096

O comando xargs --show-limits confirma um pouco disso:

Your environment variables take up 3134 bytes
POSIX upper limit on argument length (this system): 2091970
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2088836
Size of command buffer we are actually using: 131072

sysconf foi projetado inicialmente para encontrar o valor do sistema para a variável PATH e, em seguida, foi estendido para outras variáveis. Agora, a documentação do Open Group explora as razões para ter tal framework onde as aplicações podem pesquisar variáveis de sistema em tempo de execução, e as considerações práticas relacionadas sobre a linha de base ...:

(...) If limited to the most restrictive values in the headers, such applications would have to be prepared to accept the most limited environments offered by the smallest microcomputers. Although this is entirely portable, there was a consensus that they should be able to take advantage of the facilities offered by large systems, without the restrictions associated with source and object distributions.

During the discussions of this feature, it was pointed out that it is almost always possible for an application to discern what a value might be at runtime by suitably testing the various functions themselves. And, in any event, it could always be written to adequately deal with error returns from the various functions. In the end, it was felt that this imposed an unreasonable level of complication and sophistication on the application developer.

... bem como as deficiências de tal configuração no que se refere a algumas variáveis de arquivo com fpathconf :

The pathconf() function was proposed immediately after the sysconf() function when it was realized that some configurable values may differ across file system, directory, or device boundaries.

For example, {NAME_MAX} frequently changes between System V and BSD-based file systems; System V uses a maximum of 14, BSD 255. On an implementation that provides both types of file systems, an application would be forced to limit all pathname components to 14 bytes, as this would be the value specified in on such a system.

Portanto, a intenção era aliviar os desenvolvedores de alguns obstáculos para a linha de base e, ao mesmo tempo, reconhecer a variedade nos sistemas de arquivos e, geralmente, permitir a personalização em diferentes variantes da plataforma. A evolução do hardware, Unix e padrões relacionados (C e POSIX) tem um papel aqui.

Perguntas:

  • O comando getconf não tem uma opção "list" e set , printenv ou export não mostram essas variáveis. Existe um comando que lista seu valor?
  • Por que instalações como fpathconf foram criadas para introduzir mais flexibilidade, mas apenas para variáveis de sistema relacionadas a arquivos e PATH? É só porque naquele momento o getconf era apenas sobre o PATH?
  • Qual é a implementação atual do Linux e é compatível com POSIX? No Q vinculado, há referência em as respostas para ARG_MAX variando com o tamanho da pilha ("no Linux 3.11 ... um quarto do limite definido no tamanho da pilha, ou 128kiB se for menor que 512kiB"):
    • Qual é a razão para isso?
    • Essa escolha (1/4 do tamanho da pilha) é uma implementação específica do Linux ou apenas um recurso na implementação básica ou a implementação histórica do UNIX sempre rendeu basicamente 1/4 do tamanho da pilha?
    • Muitas outras variáveis além do ARG_MAX são uma função do tamanho stack ou recursos semelhantes ou a importância dessa variável garante um tratamento especial?
    • Praticamente, alguém entrega um sistema / solução Linux compatível com POSIX e há uma configuração do limite de tamanho de pilha, por exemplo, para permitir que algum aplicativo ultrapasse as especificações máximas básicas se for escalonado com o hardware ou se for uma prática customizar diretamente limits.h e compila para necessidades específicas?
    • Qual é a diferença para algo como ARG_MAX entre usar limits.h vs. alterar a variável em tempo de execução com algo como ulimit -s comando vs. tendo o kernel gerenciado diretamente? Em particular, o valor (baixo) dessa variável no meu limits.h obsoleto no Linux por causa das alterações do kernel, ou seja, foi substituído?
  • A linha de comando supostamente tem restrições de comprimento específicas do shell que não estão relacionadas à expansão e ao ARG_MAX; o que são em bash ?
por jus cogens prime 22.01.2014 / 08:45

1 resposta

2

Não há uma maneira padrão de recuperar a lista de variáveis de configuração que são suportadas em um sistema. Se você programar para uma determinada versão POSIX, a lista nessa versão da especificação POSIX é sua lista de referência. No Linux, getconf -a lista todas as variáveis disponíveis.

fpathconf não é específico do PATH. É sobre variáveis relacionadas a arquivos, que são aquelas que podem variar de arquivo para arquivo.

Em relação ao ARG_MAX no Linux, a justificativa para depender do tamanho da pilha é que os argumentos acabam na pilha, então é melhor que haja espaço suficiente para eles, além de tudo o mais que deve caber. A maioria das outras implementações (incluindo versões mais antigas do Linux) tem um tamanho fixo.

A maioria dos limites combina com a disponibilidade de recursos, com recursos diferentes dependendo do limite. Por exemplo, um processo pode não conseguir abrir um arquivo mesmo se ele tiver menos de OPEN_MAX de arquivos abertos, se o sistema estiver sem memória que pode ser usada para os dados relacionados a arquivos.

Por padrão, o Linux é compatível com POSIX neste ponto, então não sei onde você está chegando.

Se você usar ulimit -s para restringir o tamanho da pilha a menos de ARG_MAX , estará tornando o sistema não mais compatível. Um sistema POSIX pode ser feito de várias maneiras, incluindo PATH=/nowhere (tornando todos os utilitários padrão indisponíveis) ou rm -rf / .

O valor de ARG_MAX em limits.h fornece um mínimo que os aplicativos podem confiar. Um sistema compatível com POSIX pode permitir que execve seja bem-sucedido, mesmo se os argumentos excederem esse tamanho. A garantia relacionada a ARG_MAX é que, se os argumentos couberem nesse tamanho, execve não falhará devido E2BIG .

    
por 23.01.2014 / 01:32