O que os “recursos ativados” no GNU acham?

8

Quando uso find --versioncom o GNU find, recebo algo assim:

find (GNU findutils) 4.5.9     
[license text]
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS(FTS_CWDFD) CBO(level=2)

O que esses "recursos" significam? Há alguma referência a O_NOFOLLOWser uma medida de segurança man finde há uma menção de LEAF_OPTIMISATIONuma otimização que salva algumas lstatchamadas em nós de folha. Mas não consigo encontrar nada sobre FTS, D_TYPEou CBO.

nneonneo
fonte
1
Este parece ser o fim da escada. Talvez pudesse forçar alguém a ler o código-fonte do find. Prometa alguns chocolates.
ott--

Respostas:

8

Esta é uma resposta completa derivada das respostas de Ketan e Daniel Kullman, bem como de minha própria pesquisa.

A maioria dos "recursos" acaba sendo otimizações de consulta, pois findgeralmente é capaz de (quase) consultas arbitrariamente complexas no sistema de arquivos.


D_TYPE

A presença do D_TYPErecurso significa que findfoi compilado com suporte para o d_typecampo em struct dirent. Este campo é uma extensão BSD também adotada pelo Linux, que fornece o tipo de arquivo (diretório, arquivo, pipe, soquete, dispositivo char / block, etc.) na estrutura retornada por readdire amigos. Como otimização, você findpode usar isso para reduzir ou eliminar lstatchamadas quando -typeé usada como uma expressão de filtro.

readdirnem sempre pode ser preenchido d_typeem alguns sistemas de arquivos; portanto, algumas vezes lstatainda será necessário.

Mais informações da documentação oficial: https://www.gnu.org/software/findutils/manual/html_node/find_html/d_005ftype-Optimisation.html

O_NOFOLLOW

Esta opção lerá (enabled)ou (disabled). Se presente e ativado, esse recurso implementa uma medida de segurança que protege findde determinados ataques de corrida do TOCTTOU. Especificamente, impede a findpassagem de um link simbólico durante a passagem do diretório, o que poderia ocorrer se o diretório fosse substituído por um link simbólico após a verificação do tipo de arquivo do diretório, mas antes da inserção do diretório.

Com essa opção ativada, findserá usado open(..., O_NOFOLLOW)no diretório para abrir apenas diretórios reais e, em seguida, será usado openatpara abrir arquivos nesse diretório.

LEAF_OPTIMISATION

Essa otimização ligeiramente obscura permite finddeduzir quais subdiretórios de um diretório pai são diretórios usando a contagem de links do diretório pai, pois os subdiretórios contribuirão para a contagem de links do pai (via ..link). Em certas circunstâncias, permitirá findcancelar uma statchamada. No entanto, se o sistema de arquivos ou o SO apresentar uma representação incorreta st_nlinks, poderá causar findresultados falsos (felizmente, é uma ocorrência muito rara).

Mais informações na documentação oficial: https://www.gnu.org/software/findutils/manual/html_node/find_html/Leaf-Optimisation.html

STF

Quando ativado, o FTSrecurso faz findcom que a ftsAPI use a hierarquia de arquivos, em vez de uma implementação recursiva direta.

Não está claro para mim qual é a vantagem fts, mas FTSé basicamente o padrão em todas as findversões padrão que vi até agora.

Mais informações: https://www.gnu.org/software/findutils/manual/html_node/find_html/fts.html , http://man7.org/linux/man-pages/man3/fts.3.html

CBO

Acontece (depois de ler o findcódigo-fonte sugerido por daniel kullman) que "CBO" se refere ao nível de otimização de consulta (significa "otimizador baseado em custo"). Por exemplo, se eu fizer find -O9001 --version, eu recebo

Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION FTS() CBO(level=9001) 

Olhando para a -Oopção man find, vejo

-Olevel
  Enables query optimisation.   The find program reorders tests to speed up execution  while  preserving  the  overall
  effect; that is, predicates with side effects are not reordered relative to each other.  The optimisations performed
  at each optimisation level are as follows.

  0      Equivalent to optimisation level 1.

  1      This is the default optimisation level  and  corresponds  to  the  traditional  behaviour.   Expressions  are
         reordered  so that tests based only on the names of files (for example -name and -regex) are performed first.

  2      Any -type or -xtype tests are performed after any tests based only on the names  of  files,  but  before  any
         tests  that  require information from the inode.  On many modern versions of Unix, file types are returned by
         readdir() and so these predicates are faster to evaluate than predicates which need to stat the file first.

  3      At this optimisation level, the full cost-based query optimiser is enabled.  The order of tests  is  modified
         so  that  cheap  (i.e. fast) tests are performed first and more expensive ones are performed later, if neces-
         sary.  Within each cost band, predicates are evaluated earlier or later according to whether they are  likely
         to  succeed or not.  For -o, predicates which are likely to succeed are evaluated earlier, and for -a, predi-
         cates which are likely to fail are evaluated earlier.

  The cost-based optimiser has a fixed idea of how likely any given test is to succeed.  In some cases the probability
  takes  account of the specific nature of the test (for example, -type f is assumed to be more likely to succeed than
  -type c).  The cost-based optimiser is currently being evaluated.   If it does not actually improve the  performance
  of find, it will be removed again.  Conversely, optimisations that prove to be reliable, robust and effective may be
  enabled at lower optimisation levels over time.  However, the default behaviour (i.e. optimisation level 1) will not
  be  changed  in  the 4.3.x release series.  The findutils test suite runs all the tests on find at each optimisation
  level and ensures that the result is the same.

Mistério resolvido! É um pouco estranho que a opção seja um valor de tempo de execução; normalmente, eu esperaria que a --versionsaída refletisse apenas as opções em tempo de compilação.

nneonneo
fonte
1

As informações O_NOFOLLOWsão fornecidas na infopágina de find:

9.2.1.1 O_NOFOLLOW

..................

Se o seu sistema suportar o sinalizador O_NOFOLLOW (1), a open(2)' system call,localização 'o utilizará ao alterar o diretório com segurança. O diretório de destino é aberto primeiro e, em seguida find' changes working directory with the, a chamada do sistema fchdir (). Isso garante que os links simbólicos não sejam seguidos, impedindo o tipo de ataque da condição de corrida em que são usados ​​links simbólicos.

...

Na árvore de origem, CBOocorre apenas no arquivo parser.c:

 printf("CBO(level=%d) ", (int)(options.optimisation_level)); 

indicando que é otimização baseada em custos (meu melhor palpite).

D_TYPE ocorre em vários locais na árvore de origem e parece ter a ver com o tipo de entrada do diretório:

$ grep 'D_TYPE' */**

Rendimentos:

find/parser.c:#if defined USE_STRUCT_DIRENT_D_TYPE && defined HAVE_STRUCT_DIRENT_D_TYPE
lib/savedirinfo.c:#if defined HAVE_STRUCT_DIRENT_D_TYPE && defined USE_STRUCT_DIRENT_D_TYPE

e mais algumas entradas. Você pode encontrar a fonte aqui .

mkc
fonte
0

Ao examinar a árvore de fontes findutils ( http://git.savannah.gnu.org/cgit/findutils.git/tree/ ), encontrei o seguinte:

  • configure.ac: --enable-d_type-optimization, use os dados do tipo de arquivo retornados em struct dirent.d_type por readdir ()),
  • m4 / withfts.m4: --without-fts Use um mecanismo mais antigo para pesquisar no sistema de arquivos, em vez de usar fts ()

Não encontrei nada sobre a CBO; pode ser necessário fazer o download do código-fonte e procurar o termo.

daniel kullmann
fonte