在 GNU/Linux 中区分目录和 btrfs 子卷的最佳方法是什么?
我知道它们看起来应该是一样的,这很酷。但出于维护目的,当我查看目录时,我想知道它是否只是一个目录,或者它是否是一个子卷。 (就此而言,最好知道它是否已安装,如果已安装,如何安装以及从何处安装。)
目的:我想修改我的子卷的结构,例如建议的那样这里。我需要一种方法来查看我在做什么,以便检查我在做什么。谢谢。 :-)
我看过的:
的输出ls -d
或者tree -d
显示文件夹,但不区分目录和Btrfs 子卷。使用ls -l
它们实际上看起来是一样的。
甚至ls --classify
和ls --file-type
似乎没有澄清这种区别。
可能的解决方案:
我发现我可以检查文件夹的索引节点号,如果是256这就是说它是一个子卷。 (参考文献1,2,3)
那么使用 inode=256 是区分目录和子卷的最佳启发式方法吗? (我假设在某些底层文件系统中,可能还有另一个原因导致 inode =256。因此,要进行明确的检查,您还必须确保有问题的目录是 btrfs 文件系统的一部分。 )
另一种方法可能是通过命令btrfs subversion list .
然后解析输出。您必须添加此mount | grep /\
或类似的内容来处理 btrfs 磁盘、磁盘、分区的根挂载(视情况而定)。
未来: 我认为如果有一些新的选择那就太好了ls
这将提供有关子卷和安装点的信息,可能采用类似于软链接显示方式的格式,即
$ ls --show-mounts
/ <-- mounted from /dev/sdc
.snapshots <-- subvolume of /
shapshot <-- subvolume of .snapshots mounted to it's folder /2
背景:
目录和子卷的管理方式截然不同。
您不能使用
rmdir
或rm -rf
删除子卷,而必须使用btrfs subvolume delete
。除非您位于一个特定的子卷中,否则您无法硬链接目录或文件。
子卷显示为自动安装,但也可以手动安装到不同的安装点。
如果你使用鲷鱼或者拍快照,快照实际上是子卷,至少是一种特殊类型的子卷。
例如,你的根树可能看起来像这样:
/ /.snapshots /.snapshots/1 /.snapshots/1/snapshot /.snapshots/2 /.snapshots/2/snapshot ...
这里只有
/1
和/2
是普通目录,而/
、/.snapshots
和/snapshot
似乎是 btrfs 子卷。
答案1
btrfs subvolume show /directory/in/question
您很可能需要sudo
.如果它是子卷,则该命令将成功;否则它会失败。您可以将输出重定向到/dev/null
并仅依赖于退出状态。
这将测试目录树中的每个可用目录:
sudo find / -type d -exec sh -c '
for d do
btrfs subvolume show "$d" >/dev/null 2>&1 && printf "%s\n" "$d"
done' find-sh {} +
您可能想要排除无法怀疑的路径。以下代码排除/proc
,/sys
和/dev
:
sudo find / -type d \( \
\( -path /proc -prune \) -o \
\( -path /sys -prune \) -o \
\( -path /dev -prune \) -o \
\( -exec sh -c '
for d do
btrfs subvolume show "$d" >/dev/null 2>&1 && printf "%s\n" "$d"
done
' find-sh {} + \) \)
有关的:如何确定目录/文件位于哪个子卷?
答案2
st_dev
返回的字段(stat(2)
称为包含文件的设备的 ID)在 BTRFS 子卷以及文件系统之间是不同的。使用命令行,即
if [ btrfs != "$(findmnt -noFSTYPE --target=.)" ]
then
echo "not btrfs"
elif findmnt . >/dev/null
then
echo "btrfs mountpoint"
elif [ "$(stat -c%d .)" -ne "$(stat -c%d ..)" ]
then
echo "btrfs subvolume"
else
echo "btrfs directory"
fi