在正在运行的 Linux 系统上,有什么可移植的(在 Linux 发行版中)方法来找出当前内核已编译(不通过模块)支持哪些文件系统?
以我当前的 Ubuntu x86_64 内核为例3.11.0-24-generic #41-Ubuntu
:例如,它有 no /proc/config.gz
,否则这将是我的第一个想法。
我感兴趣的原因是我想(以编程方式)使用当前内核和内核能够加载/安装的初始 ramdisk 构建一个救援环境。
就像比较一样简单 /proc/filesystems
和 lsmod
?
lsmod
如果是这样:模块是否始终具有与文件系统名称(中的最后一列)完全相同的名称(输出的第一列/proc/filesystems
)?
是否有一种更现代的方式,例如/sys
代替/proc
寻找信息?
我目前的方法如下。有人可以确认它是正确的,或者建议如何做吗?:
for fscand in $(awk '{print $NF}' /proc/filesystems)
do
if test $(lsmod | grep -c -e '^'${fscand}'[^a-z0-9_-]') -eq 0
then
candlist="${fscand} ${candlist}"
fi
done
for fscand in $candlist
do
echo $fscand is compiled-in
done
答案1
/proc/filesystems
是不是就跟比较一样简单lsmod
?
不:
$ comm -31 <(lsmod | awk 'NR!=1 {print $1}' |sort) \
<(</proc/filesystems awk '{print $NF}' |sort) | fmt
anon_inodefs autofs bdev cgroup cpuset debugfs devpts devtmpfs ext2 ext3
fuseblk fusectl hugetlbfs mqueue nfs4 pipefs proc pstore ramfs rootfs
rpc_pipefs securityfs sockfs sysfs tmpfs
其中许多都没有内置到该系统的内核中。autofs
由名为 的模块提供,autofs4
而nfs4
由名为 的模块提供nfs
。该ext4
模块提供ext2
和;提供和。(不要与 混淆)由 提供。ext3
ext4
fuse
fuseblk
fusectl
rpc_pipefs
pipefs
sunrpc
然而,您的系统能够按需加载文件系统的模块:当您运行时mount -t foo …
,如果foo
不是受支持的文件系统类型,Linux 会尝试加载提供此文件系统的模块。其工作原理是内核检测到这foo
不是受支持的文件系统,并调用modprobe
加载名为 的模块fs-foo
。该机制类似于pci:…
别名,通过 PCI ID 加载 PCI 硬件外设的驱动程序usb:…
这与 USB 类似 — 请参阅如何为设备分配 USB 驱动程序和Debian 重启后未检测到串行 PCI 卡以获得更多解释。模块fs-…
别名记录在/lib/$(uname -r)/modules.alias
.该文件是在构建内核时生成的。
在正常情况下,您可以使用它来确定模块提供了哪些文件系统。通过消除,模块未提供的文件系统被内置到内核中。在极少数情况下,这种方法不起作用,例如,如果您修改或删除了文件modules.alias
,或者文件系统既由模块提供又以编译形式提供。我不知道有什么方法可以处理这些情况,除非编写一些内核代码并将其作为模块加载。
for fs in $(</proc/filesystems awk '{print "fs-" $NF}' |sort); do
/sbin/modprobe -n $fs 2>/dev/null || echo "$fs is built in"
done