Linux 下 zfs 上“find”的行为不一致

Linux 下 zfs 上“find”的行为不一致

今天我检查了我的系统上是否有多个 python 副本,然后我发现了一些非常奇怪的行为find

mark@neverland:~/repos/lpod-python$ ls -i /bin/python3.10
534638 /bin/python3.10
mark@neverland:~/repos/lpod-python$ ls -i /usr/bin/python3.10
534638 /usr/bin/python3.10

可以看到,两个路径的 inode 是相同的,运行后find /usr/bin ...得到预期结果:

mark@neverland:~/repos/lpod-python$ find /usr/bin -samefile /bin/python3.10
/usr/bin/python3.10
mark@neverland:~/repos/lpod-python$ find /usr/bin -inum 534638
/usr/bin/python3.10

但运行find /bin ...没有结果:

mark@neverland:~/repos/lpod-python$ find /bin -samefile /usr/bin/python3.10
mark@neverland:~/repos/lpod-python$ find /bin -inum 534638
mark@neverland:~/repos/lpod-python$ 

我以前运行过很多 Solaris 服务器,但这是我第一次在 Linux 下使用 zfs。我让 Ubuntu 安装程序运行,结果比我预期的要忙得多——/etc/mtab长达 89 行!所以我倾向于认为问题就出在这里。

mark@neverland:~/repos/lpod-python$ zfs list -t all

NAME                                               USED  AVAIL     REFER  MOUNTPOINT
...
rpool/ROOT/ubuntu_8me7yq                          12.1G   169G     5.45G  /
rpool/ROOT/ubuntu_8me7yq/srv                        96K   169G       96K  /srv
rpool/ROOT/ubuntu_8me7yq/usr                       224K   169G       96K  /usr

如您所见,zfs list显示/bin/usr/bin位于不同的挂载点(分别为//usr)。如果是这样,那可以解释意外行为find(尽管它仍然没有真正解释不一致行为)。但不要这么快!更多 WTFery:

mark@neverland:~/repos/lpod-python$ zfs get mountpoint /bin/python3.10
NAME                      PROPERTY    VALUE       SOURCE
rpool/ROOT/ubuntu_8me7yq  mountpoint  /           local
mark@neverland:~/repos/lpod-python$ zfs get mountpoint /usr/bin/python3.10
NAME                      PROPERTY    VALUE       SOURCE
rpool/ROOT/ubuntu_8me7yq  mountpoint  /           local

我甚至不知道如何开始排除故障。为什么我的电脑会欺骗我?!?

答案1

您的 /bin 很可能是指向 /usr/bin 的符号链接(这在 Linux 发行版中变得越来越常见,并且我相信自 SunOS 4 以来在 Solaris 中也是如此),但“find”不会遵循在命令行中直接指定的符号链接——它根本不会进入目标目录,因此您的过滤器永远不会与 /bin/python3.10 进行比较:

$ find /bin
/bin
$
$ find /bin -ls
 28508001    4 lrwxrwxrwx   1 root  root       7 Oct 19 00:01 /bin -> usr/bin
$

...除非-H给出选项:

$ find -H /bin -ls
  2883593   72 drwxr-xr-x   5 root  root   69632 Nov 14 14:24 /bin
  2898531   28 -rwxr-xr-x   1 root  root   26536 Nov  1 14:46 /bin/ktutil
  2900363   84 -rwxr-xr-x   1 root  root   84320 Aug 30 00:49 /bin/pinentry-gtk-2
  2902165    0 lrwxrwxrwx   1 root  root      17 Jul 25 17:16 /bin/ip6tables-save -> xtables-nft-multi
  2906823    0 lrwxrwxrwx   1 root  root      13 Nov  7 15:20 /bin/mysqlcheck -> mariadb-check
  2901613  324 -rwxr-xr-x   1 root  root  328608 Oct 14 14:01 /bin/gpg-agent
  2901954   16 -rwxr-xr-x   1 root  root   14280 Oct  7 20:28 /bin/dbus-run-session
[...]

使用以下命令可以轻松找到路径中的符号链接namei

$ namei -l /bin/python3.10
f: /bin/python3.10
drwxr-xr-x root root /
lrwxrwxrwx root root bin -> usr/bin
drwxr-xr-x root root   usr
drwxr-xr-x root root   bin
-rwxr-xr-x root root python3.10

但只有最后的此处,为“find”提供的路径的组成部分很重要——始终会遵循中间符号链接。(基本上,重要的是路径上的 lstat() 结果。)


用于findmnt以更易于阅读的方式列出 Linux 上的所有挂载。其中很多可能是 Ubuntu 的“ZSys”ZFS 集成或 Ubuntu 的“Snap”应用程序容器(它在循环挂载的文件系统映像中分发软件);其中一些将是内核文件系统,例如 /sys。(/etc/mtab 也是 /proc 中文件的符号链接,因此它包括每个挂载的文件系统,即使它以前可能跳过了一些“不感兴趣”的文件系统(当它曾经是一个常规文件时)。

相关内容