getdentsが両方のシステムで異なる結果を返すのはなぜですか?

getdentsが両方のシステムで異なる結果を返すのはなぜですか?

あるサーバーで次のような結果を得る奇妙な状況があります。

vagrant@shopping:/vagrant/deployer-example$ uname -a
Linux shopping 4.19.0-0.bpo.9-amd64 #1 SMP Debian 4.19.118-2+deb10u1~bpo9+1 (2020-06-09) x86_64 GNU/Linux


 vagrant@shopping:/vagrant/deployer-example$ bin/php --version
PHP 8.0.3 (cli) (built: Mar  5 2021 08:36:11) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.3, Copyright (c), by Zend Technologies
vagrant@shopping:/vagrant/deployer-example$ sudo ldd --version
ldd (Debian GLIBC 2.24-11+deb9u4) 2.24
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
vagrant@shopping:/vagrant/deployer-example$ php -r 'var_dump(glob("/vagrant/deployer-example/config/{routes}/*.yaml", GLOB_BRACE));'
array(4) {
  [0]=>
  string(56) "/vagrant/deployer-example/config/routes/annotations.yaml"
  [1]=>
  string(55) "/vagrant/deployer-example/config/routes/easy_admin.yaml"
  [2]=>
  string(52) "/vagrant/deployer-example/config/routes/monitor.yaml"
  [3]=>
  string(59) "/vagrant/deployer-example/config/routes/nelmio_api_doc.yaml"
}
vagrant@shopping:/vagrant/deployer-example$ php -r 'var_dump(glob("/vagrant/deployer-example/config/{routes}/*.yaml/", GLOB_BRACE));'
array(4) {
  [0]=>
  string(56) "/vagrant/deployer-example/config/routes/annotations.yaml"
  [1]=>
  string(55) "/vagrant/deployer-example/config/routes/easy_admin.yaml"
  [2]=>
  string(52) "/vagrant/deployer-example/config/routes/monitor.yaml"
  [3]=>
  string(59) "/vagrant/deployer-example/config/routes/nelmio_api_doc.yaml"
}

しかし、2番目のシステムでは

deployer-example@s2-stg-s01:~/deployer/current$ uname -a
Linux s2-stg-s01 4.19.0-0.bpo.9-amd64 #1 SMP Debian 4.19.118-2+deb10u1~bpo9+1 (2020-06-09) x86_64 GNU/Linux
deployer-example@s2-stg-s01:~/deployer/current$ bin/php --version
PHP 8.0.3 (cli) (built: Mar  5 2021 08:36:11) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.3, Copyright (c), by Zend Technologies
deployer-example@s2-stg-s01:~/deployer/current$ ldd --version
ldd (Debian GLIBC 2.24-11+deb9u4) 2.24
Copyright © 2016 Free Software Foundation, Inc.
Dies ist freie Software; in den Quellen befinden sich die Lizenzbedingungen.
Es gibt KEINERLEI Garantie; nicht einmal für die TAUGLICHKEIT oder
VERWENDBARKEIT FÜR EINEN ANGEGEBENEN ZWECK.
Implementiert von Roland McGrath und Ulrich Drepper.
deployer-example@s2-stg-s01:~/deployer/current$ php -r 'var_dump(glob("/home/deployer-example/deployer/releases/437/config/{routes}/*.yaml", GLOB_BRACE));'
array(4) {
  [0]=>
  string(75) "/home/deployer-example/deployer/releases/437/config/routes/annotations.yaml"
  [1]=>
  string(74) "/home/deployer-example/deployer/releases/437/config/routes/easy_admin.yaml"
  [2]=>
  string(71) "/home/deployer-example/deployer/releases/437/config/routes/monitor.yaml"
  [3]=>
  string(78) "/home/deployer-example/deployer/releases/437/config/routes/nelmio_api_doc.yaml"
}
deployer-example@s2-stg-s01:~/deployer/current$ php -r 'var_dump(glob("/home/deployer-example/deployer/releases/437/config/{routes}/*.yaml/", GLOB_BRACE));'
array(0) {
}

straceを使用してデバッグしていますが、最初のシステムでは次のように報告されています。

open("/vagrant/deployer-example/config/routes", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
fstat(3, {st_dev=makedev(0, 44), st_ino=86530891, st_mode=S_IFDIR|0755, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=224, st_atime=2021-03-12T15:24:14+0000, st_mtime=2021-03-12T15:19:23+0000, st_ctime=2021-03-12T15:19:23+0000}) = 0
brk(0x562b5bb63000)                     = 0x562b5bb63000
getdents(3, [{d_ino=1031795, d_off=1, d_reclen=24, d_name=".", d_type=DT_UNKNOWN}, {d_ino=1031796, d_off=2, d_reclen=24, d_name="..", d_type=DT_UNKNOWN}, {d_ino=1031797, d_off=3, d_reclen=40, d_name="annotations.yaml", d_type=DT_UNKNOWN}, {d_ino=1031798, d_off=4, d_reclen=24, d_name="dev", d_type=DT_UNKNOWN}, {d_ino=1031799, d_off=5, d_reclen=40, d_name="easy_admin.yaml", d_type=DT_UNKNOWN}, {d_ino=1031800, d_off=6, d_reclen=32, d_name="monitor.yaml", d_type=DT_UNKNOWN}, {d_ino=1031801, d_off=7, d_reclen=40, d_name="nelmio_api_doc.yaml", d_type=DT_UNKNOWN}], 32768) = 224
newfstatat(3, "annotations.yaml", {st_dev=makedev(0, 44), st_ino=87279600, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=135, st_atime=2021-03-12T15:19:24+0000, st_mtime=2021-03-12T15:19:23+0000, st_ctime=2021-03-12T15:19:23+0000}, 0) = 0
newfstatat(3, "easy_admin.yaml", {st_dev=makedev(0, 44), st_ino=87279603, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=127, st_atime=2021-03-05T16:00:41+0000, st_mtime=2021-03-05T16:00:41+0000, st_ctime=2021-03-05T16:00:41+0000}, 0) = 0
newfstatat(3, "monitor.yaml", {st_dev=makedev(0, 44), st_ino=87279604, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=137, st_atime=2021-03-05T16:00:41+0000, st_mtime=2021-03-05T16:00:41+0000, st_ctime=2021-03-05T16:00:41+0000}, 0) = 0
newfstatat(3, "nelmio_api_doc.yaml", {st_dev=makedev(0, 44), st_ino=87279605, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=367, st_atime=2021-03-05T16:00:41+0000, st_mtime=2021-03-05T16:00:41+0000, st_ctime=2021-03-05T16:00:41+0000}, 0) = 0
getdents(3, [], 32768)                  = 0
close(3)                                = 0

しかし、2番目の場合

open("/home/deployer-example/deployer/releases/437/config/routes", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 5
fstat(5, {st_dev=makedev(8, 17), st_ino=123601048, st_mode=S_IFDIR|0755, st_nlink=3, st_uid=1084, st_gid=1084, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=2021-03-12T16:18:27+0100.512902323, st_mtime=2021-03-12T16:17:55+0100.984164843, st_ctime=2021-03-12T16:17:55+0100.984164843}) = 0
brk(0x557145c2a000)                     = 0x557145c2a000
getdents(5, [{d_ino=123601055, d_off=2396884471359371616, d_reclen=40, d_name="nelmio_api_doc.yaml", d_type=DT_REG}, {d_ino=123601053, d_off=2713394375622026215, d_reclen=32, d_name="monitor.yaml", d_type=DT_REG}, {d_ino=123601049, d_off=3087430337415459848, d_reclen=40, d_name="easy_admin.yaml", d_type=DT_REG}, {d_ino=123601050, d_off=7440370618885146051, d_reclen=24, d_name="dev", d_type=DT_DIR}, {d_ino=123600993, d_off=8681975314043990400, d_reclen=24, d_name="..", d_type=DT_DIR}, {d_ino=123601479, d_off=9220757504948275036, d_reclen=40, d_name="annotations.yaml", d_type=DT_REG}, {d_ino=123601048, d_off=9223372036854775807, d_reclen=24, d_name=".", d_type=DT_DIR}], 32768) = 224
getdents(5, [], 32768)                  = 0
close(5)                                = 0

どちらのシステムも同じDebianバージョン、EXT4ファイルシステムで実行され、同じAnsibleスクリプトがマウントされているため、同じコアパッケージも必要です。

どのように犯人で範囲を絞り込むことができますか?これら2つのサーバーが異なる動作をする理由は何ですか?

ベストアンサー1

-v見てわかるように、これらのgetdents呼び出しは最初のシステムでは返されますが、strace()の詳細モードが有効になり、2番目のシステムd_type=DT_REGでは返されませんd_type=DT_UNKNOWN。その理由は、最初のケースでは使用されているファイルシステムがあり、ext42番目のケースではそれがあるためですprl_fsprl_fsファイルシステム自体は明らかにKnownを返しませんd_type

これはglibcのglob()関数で極端なケースを引き起こします。 glibcのバグが報告されました:https://sourceware.org/bugzilla/show_bug.cgi?id=25659

また、Parallels サポートに連絡し、DT_UNKNOWN を d_type に返却するのを中止するよう依頼しました。 Parallels 16.5.0-49183以降、この問題は解決されました。 :)

おすすめ記事