【问题标题】:How to test if location is a btrfs subvolume?如何测试位置是否是 btrfs 子卷?
【发布时间】:2014-09-18 08:49:01
【问题描述】:

在 bash 脚本中,如何优雅地检查特定位置是否是 btrfs 子卷?

我不想知道给定位置是否 btrfs 文件系统(或子卷)中。我想知道给定的位置是否是子卷。

理想情况下,解决方案可以用 bash 函数编写,这样我就可以编写:

if is_btrfs_subvolume $LOCATION; then
    # ... stuff ...
fi 

一个“优雅”的解决方案应该是可读的、代码量少、资源消耗少。

【问题讨论】:

    标签: bash btrfs


    【解决方案1】:

    子卷由 inode 编号 256 标识,因此您可以简单地通过

    if [ `stat --format=%i /path` -eq 256 ]; then ...; fi
    

    还有一个所谓的空子卷,即。如果对嵌套子卷进行快照,则该实体将代替原始子卷存在。它的 inode 编号为 2。

    为了一般可靠地检查任何目录是否为子卷,还应验证文件系统类型

    stat -f --format=%T /path
    

    【讨论】:

    • 与当前提供的解决方案相比,所有这些似乎都过于复杂,并且如果使用任何新的 inode 编号就会变得脆弱,不是吗?无论如何,我喜欢你提供的额外外围信息,实际上可能有一个很好的解决方案隐藏不了。
    • 命令“btrfs subvolume list”需要root权限,因为它使用特权ioctl来读取有关子卷的信息,原始答案中没有提到这一点。基于 inode 编号的测试没有这样的限制。接下来,我不明白“如果使用任何新的 inode 编号就会变得脆弱”是什么意思。每个子卷的 inode 编号为 256,这不会改变。子卷中的常规文件和目录的 inode 编号为 257 或更高。
    • 你是对的。你的回答很好,只错过了 bash 函数实现(最初被问到),它也是一个很好的 TLDR 测试总结。
    【解决方案2】:

    解决方案1:使用@kdave 建议:

    is_btrfs_subvolume() {
        local dir=$1
        [ "$(stat -f --format="%T" "$dir")" == "btrfs" ] || return 1
        inode="$(stat --format="%i" "$dir")"
        case "$inode" in
            2|256)
                return 0;;
            *)
                return 1;;
        esac
    }
    

    解决方案2:我之前用过的(只有一次调用,但可能很脆弱):

    is_btrfs_subvolume() {
        btrfs subvolume show "$1" >/dev/null 2>&1
    }
    

    编辑:更正list 并将其替换为show,因为list 的行为在任何正常的btrfs 目录上都无法正确回答。

    EDIT2:由于@kdave 没有发布他出色答案的完整版本,我将其添加到我的答案中。

    【讨论】:

    • 此功能无效。就我而言,$1 是 btrfs 分区中存在的任何目录,将始终返回此分区中的所有子卷列表,尽管 $1 只是一个普通目录。如果当前目录是子卷,则该目录将作为列表的最后一行列出,否则不列出。我不知道该怎么回答...
    • 哦,是的,很好。抱歉,我将“列表”替换为“显示”。它现在是否正常工作?
    • 你应该以 root 身份运行你的脚本。
    • 这仍然对您有用吗?该命令正确识别子卷,但总是为我返回 0,这意味着我不能以编程方式使用它。
    • @TomWadley 仍然在这里工作。你用的是什么版本的btrfs-tools? (btrfs --version...我在v4.10.1。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多