为什么特定挂载上的 df 会迭代所有挂载?

为什么特定挂载上的 df 会迭代所有挂载?

运行时df /nfs/mount/point,我预计它会比 更快df | grep /nfs/mount/point,因为它不会是stat所有其他安装点。

strace显示stat已执行所有 NFS 挂载,然后显示特定挂载点的输出。

这是一个错误吗?或者有什么更深层次的原因需要检查所有挂载点吗?

我在 CentOS 6.6、内核为 2.6.32 的 df 版本 8.4 上看到了这一点。

示例输出(经过编辑以删除公司信息)

$ strace df /home/user1/some/Directory
~  
~  
stat("/home/user2", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0  
stat("/home/user3", {st_mode=S_IFDIR|0777, st_size=20480, ...}) = 0  
stat("/home/user4", {st_mode=S_IFDIR|0777, st_size=36864, ...}) = 0  
stat("/home/user5", {st_mode=S_IFDIR|0755, st_size=663552, ...}) = 0  
stat("/software/bin", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0  
stat("/scratch/space", {st_mode=S_IFDIR|0777, st_size=8192, ...}) = 0  
stat("/eng/tools", {st_mode=S_IFDIR|0755, st_size=20480, ...}) = 0  
~  
~

答案1

这似乎已在新版本中修复。在df我的 Debian 系统(df版本 8.23)上,我得到:

$ strace -e stat df >/dev/null 
stat("/sys", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
stat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
stat("/dev", {st_mode=S_IFDIR|0755, st_size=3920, ...}) = 0
stat("/dev/pts", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/run", {st_mode=S_IFDIR|0755, st_size=1360, ...}) = 0
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/run/lock", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=80, ...}) = 0
stat("/sys/fs/pstore", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/run/shm", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=220, ...}) = 0
stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/mnt/bigboy", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
stat("/mnt/movies", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
stat("/sys/fs/fuse/connections", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/nfs_shares/lacoloc", {st_mode=S_IFDIR|0754, st_size=20480, ...}) = 0
stat("/nfs_shares/movies", {st_mode=S_IFDIR|0777, st_size=24576, ...}) = 0
stat("/nfs_shares/music", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
stat("/nfs_shares/series", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
stat("/winblows", {st_mode=S_IFDIR|0777, st_size=8192, ...}) = 0
stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=520, ...}) = 0
stat("/run/rpc_pipefs", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
stat("/proc/sys/fs/binfmt_misc", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/sys/fs/cgroup", {st_mode=S_IFDIR|0755, st_size=60, ...}) = 0
stat("/run/cgmanager/fs", {st_mode=S_IFDIR|0755, st_size=240, ...}) = 0
stat("/run/user/1000", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/proc/fs/nfsd", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/run/user/120", {st_mode=S_IFDIR|0700, st_size=100, ...}) = 0
stat("/run/user/1002", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/run/user/1003", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/run/user/1004", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/run/user/1001", {st_mode=S_IFDIR|0700, st_size=120, ...}) = 0
stat("/run/user/1001/gvfs", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
stat("/dev/cgroup/cpu", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
stat("/dev", {st_mode=S_IFDIR|0755, st_size=3920, ...}) = 0
stat("/run", {st_mode=S_IFDIR|0755, st_size=1360, ...}) = 0
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/run/lock", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=80, ...}) = 0
stat("/sys/fs/pstore", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/run/shm", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=220, ...}) = 0
stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/mnt/bigboy", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
stat("/mnt/movies", {st_mode=S_IFDIR|0777, st_size=4096, ...}) = 0
stat("/winblows", {st_mode=S_IFDIR|0777, st_size=8192, ...}) = 0
stat("/tmp", {st_mode=S_IFDIR|S_ISVTX|0777, st_size=520, ...}) = 0
stat("/proc/sys/fs/binfmt_misc", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/sys/fs/cgroup", {st_mode=S_IFDIR|0755, st_size=60, ...}) = 0
stat("/run/cgmanager/fs", {st_mode=S_IFDIR|0755, st_size=240, ...}) = 0
stat("/run/user/1000", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/proc/fs/nfsd", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
stat("/run/user/120", {st_mode=S_IFDIR|0700, st_size=100, ...}) = 0
stat("/run/user/1002", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/run/user/1003", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/run/user/1004", {st_mode=S_IFDIR|0700, st_size=60, ...}) = 0
stat("/run/user/1001", {st_mode=S_IFDIR|0700, st_size=120, ...}) = 0
stat("/run/user/1001/gvfs", {st_mode=S_IFDIR|0500, st_size=0, ...}) = 0
stat("/dev/cgroup/cpu", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
+++ exited with 0 +++

但当给出一个文件系统时,仅检查目标文件系统:

$ strace -e stat df /home/ >/dev/null 
stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/home/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
+++ exited with 0 +++

答案2

我将把这个作为部分答案;我无法解释为什么 gnulib/coreutils 开发人员选择这样做。

你可以看到在http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/df.c#n1681df 源代码询问已安装文件系统的列表。该函数的来源,开始于http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/mountlist.c#n418,循环遍历每个已安装的文件系统(通过 /proc/self/mountinfo)。只有稍后才会打印明确提到的文件系统。

相关内容