btrfs — 错误:无法销毁子卷/快照:操作不允许

btrfs — 错误:无法销毁子卷/快照:操作不允许

我们用文件系统因其出色的快照功能而广受好评。但最近,仅在一个系统上,当我清除旧快照时,我开始收到以下错误:

btrfs subvolume delete ...
ERROR: Could not destroy subvolume/snapshot: Operation not permitted
WARNING: deletion failed with EPERM, send may be in progress

删除 btrfs 快照失败的原因有很多,例如子卷存在、卷上有任何锁定文件等。注意:快照卷上的“ro”属性应该不是本身就可以防止删除。但这是我从未遇到过的情况。

经过大量调查,我发现上周的快照都设置了“不可变”属性。

lsattr <snapshot folder>
---------------------- ./221104
---------------------- ./221105
---------------------- ./221106
---------------------- ./221107
----i----------------- ./221108
----i----------------- ./221109
----i----------------- ./221110
----i----------------- ./221111
----i----------------- ./221112

由于所有快照都是使用“ro”属性集创建的,因此只需执行

chattr -i <snapshot>

结果是

chattr: Read-only file system while setting flags

必须先将快照的“只读”属性设置为 false,然后才能更改属性。我这样做了,快照删除成功了,但所有新快照仍然使用“i”属性创建!

“好吧,这就是你的问题……”

事实证明,在强化根文件系统上的挂载点时,创建快照的挂载子卷错误地设置了“不可变”属性。

在挂载点上设置“不可变”是一种很好的做法,并确保当卷挂载失败时文件夹(以及根文件系统)不会被垃圾填满。

但如果已经挂载,则“i”标志将应用于已挂载的 btrfs 卷,而不是文件夹。然后所有后续快照将共享“不可变”属性。

答案1

这是我用来清理混乱的脚本:

MyBtrfsMount=/mnt/fast_fs
SnapshotVol=/mnt/fast_fs/.snapshots
# Harden mount point
umount $MyBtrfsMount && chattr +i $MyBtrfsMount
# Clear any existing "i" on volume
mount $MyBtrfsMount && chattr -i $MyBtrfsMount
# Clear any existing "i" attributes in the snapshots
for i in $(ls -d $SnapshotVol/*)
do 
  btrfs property set $i ro false;
  chattr -i $i;
  btrfs property set $i ro true;
done

相关内容