Cosa significano le "funzionalità abilitate" in GNU find?


8

Quando uso find --versioncon GNU find, ottengo qualcosa del genere:

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

Cosa significano queste "caratteristiche"? C'è qualche riferimento O_NOFOLLOWall'essere una misura di sicurezza man finde si parla LEAF_OPTIMISATIONdell'ottimizzazione che consente di risparmiare alcune lstatchiamate sui nodi foglia. Ma non riesco a trovare nulla su FTS, D_TYPEo CBO.


1
Questa sembra essere la fine della scala. Forse potrebbe costringere qualcuno a leggere il codice sorgente di find. Prometti dei cioccolatini.
ott--

Risposte:


8

Questa è una risposta completa derivata dalle risposte di Ketan e Daniel Kullman, nonché dalla mia ricerca.

La maggior parte delle "caratteristiche" risultano essere ottimizzazioni delle query, poiché findin generale è in grado di eseguire query (quasi) arbitrariamente complesse sul filesystem.


D_TYPE

La presenza della D_TYPEfunzione indica che è findstato compilato con il supporto per il d_typecampo in struct dirent. Questo campo è un'estensione BSD adottata anche da Linux, che fornisce il tipo di file (directory, file, pipe, socket, dispositivo char / block, ecc.) Nella struttura restituita da readdire amici. Come ottimizzazione, findpuoi utilizzarlo per ridurre o eliminare le lstatchiamate quando -typeviene utilizzato come espressione di filtro.

readdirpotrebbe non essere sempre popolato d_typesu alcuni filesystem, quindi a volte è lstatancora necessario un testamento.

Maggiori informazioni dalla documentazione ufficiale: https://www.gnu.org/software/findutils/manual/html_node/find_html/d_005ftype-Optimisation.html

O_NOFOLLOW

Questa opzione leggerà (enabled)o (disabled). Se presente e abilitata, questa funzione implementa una misura di sicurezza che protegge findda determinati attacchi di razza TOCTTOU. In particolare, impedisce finddi attraversare un collegamento simbolico mentre si esegue l'attraversamento della directory, il che potrebbe verificarsi se la directory fosse sostituita da un collegamento simbolico dopo il controllo del tipo di file della directory ma prima dell'accesso alla directory.

Con questa opzione abilitata, findverrà utilizzata open(..., O_NOFOLLOW)nella directory per aprire solo directory reali, quindi utilizzare openatper aprire i file all'interno di tale directory.

LEAF_OPTIMISATION

Questa ottimizzazione leggermente oscura consente finddi dedurre quali sottodirectory di una directory padre sono directory utilizzando il conteggio dei collegamenti della directory padre, poiché le sottodirectory contribuiranno al conteggio dei collegamenti del padre (tramite il ..collegamento). In determinate circostanze, consentirà finddi eludere una statchiamata. Tuttavia, se il filesystem o il sistema operativo travisano st_nlinks, potrebbe causare findrisultati falsi (questo per fortuna è un evento molto raro).

Maggiori informazioni nella documentazione ufficiale: https://www.gnu.org/software/findutils/manual/html_node/find_html/Leaf-Optimisation.html

FTS

Quando abilitata, la FTSfunzione fa sì findche l' ftsAPI attraversi la gerarchia dei file, anziché un'implementazione ricorsiva diretta.

Non mi è chiaro quale sia il vantaggio fts, ma FTSè fondamentalmente il valore predefinito su tutte le findversioni predefinite che ho visto finora.

Ulteriori informazioni: https://www.gnu.org/software/findutils/manual/html_node/find_html/fts.html , http://man7.org/linux/man-pages/man3/fts.3.html

CBO

Si scopre (dopo aver letto il findcodice sorgente come suggerito da Daniel Kullman) che "CBO" si riferisce al livello di ottimizzazione della query (sta per "ottimizzatore basato sui costi"). Ad esempio, se lo faccio find -O9001 --version, ottengo

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

Guardando l' -Oopzione in man find, vedo

-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.

Mistero risolto! È un po 'strano che l'opzione sia un valore di runtime; di solito mi aspetto che l' --versionoutput rifletta solo le opzioni di compilazione.


1

Le informazioni su O_NOFOLLOWsono fornite nella infopagina di find:

9.2.1.1 O_NOFOLLOW

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

Se il tuo sistema supporta il flag O_NOFOLLOW (1) per la open(2)' system call,ricerca 'lo usa per cambiare directory in modo sicuro. La directory di destinazione viene prima aperta e quindi find' changes working directory with thechiamata di sistema fchdir (). Ciò garantisce che i collegamenti simbolici non vengano seguiti, impedendo il tipo di attacco delle condizioni di gara in cui viene fatto uso di collegamenti simbolici.

...

Dalla struttura di origine, si CBOverifica solo nel file parser.c:

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

indicando che si tratta di ottimizzazione basata sui costi (la mia ipotesi migliore).

D_TYPE si verifica in diversi punti dell'albero dei sorgenti e sembra avere a che fare con il tipo di voce della directory:

$ grep 'D_TYPE' */**

I rendimenti:

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 alcune altre voci. Puoi trovare la fonte qui .


0

Guardando attraverso l'albero dei sorgenti di findutils ( http://git.savannah.gnu.org/cgit/findutils.git/tree/ ), ho trovato quanto segue:

  • configure.ac: --enable-d_type-optimisation, Utilizza i dati del tipo di file restituiti in struct dirent.d_type da readdir ()),
  • m4 / withfts.m4: --without-fts Usa un meccanismo più vecchio per cercare il filesystem, invece di usare fts ()

Non ho trovato nulla su CBO; potresti dover scaricare il codice sorgente e cercare il termine ..

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.