Apa arti “fitur yang diaktifkan” di GNU temukan artinya?

8

Ketika saya gunakan find --versiondengan GNU find, saya mendapatkan sesuatu seperti ini:

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

Apa arti "fitur" ini? Ada beberapa referensi untuk O_NOFOLLOWmenjadi langkah pengamanan man find, dan ada disebutkan LEAF_OPTIMISATIONmenjadi optimasi yang menyimpan beberapa lstatpanggilan pada leaf leaf. Tetapi saya tidak dapat menemukan apa pun tentang FTS, D_TYPEatau CBO.

nneonneo
sumber
1
Ini sepertinya menjadi ujung tangga. Mungkin bisa memaksa seseorang untuk membaca kode sumber find. Janjikan beberapa cokelat.
ott--

Jawaban:

8

Ini adalah jawaban lengkap yang berasal dari jawaban Ketan dan daniel Kullman, serta penelitian saya sendiri.

Sebagian besar "fitur" berubah menjadi optimisasi kueri, karena findsecara umum mampu (hampir) pertanyaan kompleks yang kompleks pada sistem file.


D_TYPE

Kehadiran D_TYPEfitur berarti yang finddikompilasi dengan dukungan untuk d_typebidang dalam struct dirent. Bidang ini adalah ekstensi BSD yang juga diadopsi oleh Linux, yang menyediakan jenis file (direktori, file, pipa, soket, perangkat char / block, dll.) Dalam struktur yang dikembalikan dari readdirdan teman-teman. Sebagai pengoptimalan, finddapat menggunakan ini untuk mengurangi atau menghilangkan lstatpanggilan saat -typedigunakan sebagai ekspresi filter.

readdirmungkin tidak selalu terisi d_typepada beberapa sistem file, jadi terkadang lstatmasih diperlukan.

Info lebih lanjut dari dokumentasi resmi: https://www.gnu.org/software/findutils/manual/html_node/find_html/d_005ftype-Optimisation.html

O_NOFOLLOW

Opsi ini akan membaca (enabled)atau (disabled). Jika ada dan diaktifkan, fitur ini mengimplementasikan tindakan keamanan yang melindungi finddari serangan ras TOCTTOU tertentu. Secara khusus, itu mencegah finddari melintasi symlink saat melakukan direktori traversal, yang dapat terjadi jika direktori digantikan oleh symlink setelah filetype direktori diperiksa tetapi sebelum direktori dimasukkan.

Dengan opsi ini diaktifkan, findakan digunakan open(..., O_NOFOLLOW)pada direktori untuk membuka hanya direktori nyata, kemudian gunakan openatuntuk membuka file dalam direktori itu.

LEAF_OPTIMISATION

Optimasi yang sedikit tidak jelas ini memungkinkan finduntuk menyimpulkan subdirektori dari direktori induk mana yang merupakan direktori dengan menggunakan jumlah tautan dari direktori induk, karena subdirektori akan berkontribusi pada jumlah tautan induk (melalui ..tautan). Dalam keadaan tertentu, itu akan memungkinkan finduntuk menghilangkan statpanggilan. Namun, jika sistem file atau OS salah mengartikan st_nlinks, hal itu dapat menyebabkan findhasil palsu (untungnya ini kejadian yang sangat jarang).

Info lebih lanjut dalam dokumentasi resmi: https://www.gnu.org/software/findutils/manual/html_node/find_html/Leaf-Optimisation.html

FTS

Saat diaktifkan, FTSfitur menyebabkan findpenggunaan ftsAPI untuk melintasi hierarki file, alih-alih implementasi rekursif lurus.

Tidak jelas bagi saya apa keuntungannya fts, tetapi FTSpada dasarnya adalah default pada semua findversi default yang saya lihat sejauh ini.

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

KSM

Ternyata (setelah membaca findkode sumber seperti yang disarankan oleh daniel kullman) bahwa "CBO" merujuk ke tingkat optimisasi kueri (singkatan dari "pengoptimal berbasis biaya"). Misalnya, jika saya melakukannya find -O9001 --version, saya mengerti

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

Melihat -Oopsi di man find, saya melihat

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

Misteri terpecahkan! Agak aneh bahwa opsinya adalah nilai runtime; biasanya saya akan mengharapkan --versionoutput hanya untuk mencerminkan opsi waktu kompilasi.

nneonneo
sumber
1

Informasi tentang O_NOFOLLOWdiberikan di infohalaman find:

9.2.1.1 O_NOFOLLOW

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

Jika sistem Anda mendukung flag O_NOFOLLOW (1) hingga open(2)' system call,find ' gunakanlah ketika mengubah direktori dengan aman. Direktori target pertama kali dibuka dan kemudian find' changes working directory with thepanggilan sistem fchdir (). Hal ini memastikan bahwa tautan simbolik tidak diikuti, mencegah jenis serangan kondisi ras di mana penggunaan dibuat dari tautan simbolik.

...

Dari pohon sumber, CBOhanya terjadi di file parser.c:

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

menunjukkannya sebagai optimasi berbasis biaya (tebakan terbaik saya).

D_TYPE terjadi di beberapa tempat di source-tree dan sepertinya ada hubungannya dengan jenis entri direktori:

$ grep 'D_TYPE' */**

Hasil:

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

dan beberapa entri lainnya. Anda dapat menemukan sumbernya di sini .

mkc
sumber
0

Ketika mencari melalui pohon sumber findutils ( http://git.savannah.gnu.org/cgit/findutils.git/tree/ ), saya menemukan yang berikut:

  • configure.ac: --enable-d_type-optimization, Manfaatkan tipe file data yang dikembalikan dalam struct dirent.d_type oleh readdir ()),
  • m4 / withfts.m4: --without-fts Gunakan mekanisme yang lebih lama untuk mencari filesystem, daripada menggunakan fts ()

Saya tidak menemukan apa pun tentang CBO; Anda mungkin harus mengunduh kode sumber dan mencari istilah ..

daniel kullmann
sumber