Seeding device 种子设备

The COW mechanism and multiple devices under one hood enable an interesting concept, called a seeding device: extending a read-only filesystem on a device with another device that captures all writes. For example imagine an immutable golden image of an operating system enhanced with another device that allows to use the data from the golden image and normal operation. This idea originated on CD-ROMs with base OS and allowing to use them for live systems, but this became obsolete. There are technologies providing similar functionality, like unionmount, overlayfs or qcow2 image snapshot.
COW 机制和一个外壳下的多个设备实现了一个有趣的概念,称为种子设备:通过在一个设备上扩展只读文件系统,并使用另一个设备捕获所有写入。例如,想象一个不可变的操作系统黄金镜像,再加上另一个设备,允许使用黄金镜像的数据和正常操作。这个想法起源于带有基本操作系统的 CD-ROM,并允许将它们用于实时系统,但这已经过时了。有一些提供类似功能的技术,如 unionmount、overlayfs 或 qcow2 镜像快照。

The seeding device starts as a normal filesystem, once the contents is ready, btrfstune -S 1 is used to flag it as a seeding device. Mounting such device will not allow any writes, except adding a new device by btrfs device add. Then the filesystem can be remounted as read-write.
种子设备开始时作为一个普通文件系统,一旦内容准备好,使用 btrfstune -S 1 将其标记为种子设备。挂载这样的设备将不允许任何写入,除非通过 btrfs device add 添加新设备。然后文件系统可以重新挂载为读写。

Given that the filesystem on the seeding device is always recognized as read-only, it can be used to seed multiple filesystems from one device at the same time. The UUID that is normally attached to a device is automatically changed to a random UUID on each mount.
鉴于播种设备上的文件系统始终被识别为只读,因此可以使用它同时从一个设备播种多个文件系统。通常附加到设备上的 UUID 在每次挂载时会自动更改为随机 UUID。

Once the seeding device is mounted, it needs the writable device. After adding it, unmounting and mounting with umount /path; mount /dev/writable /path or remounting read-write with remount -o remount,rw makes the filesystem at /path ready for use.
一旦播种设备被挂载,它需要可写设备。添加后,使用 umount /path; mount /dev/writable /path 或使用 remount -o remount,rw 重新挂载为读写模式,使得位于 /path 的文件系统准备就绪。

Note 注意

There is a known bug with using remount to make the mount writeable: remount will leave the filesystem in a state where it is unable to clean deleted snapshots, so it will leak space until it is unmounted and mounted properly.
使用 remount 使挂载点可写存在已知 bug:remount 会使文件系统处于无法清理已删除快照的状态,因此会泄漏空间,直到正确卸载和挂载为止。

Furthermore, deleting the seeding device from the filesystem can turn it into a normal filesystem, provided that the writable device can also contain all the data from the seeding device.
此外,从文件系统中删除种子设备可以将其转换为普通文件系统,前提是可写设备还可以包含种子设备中的所有数据。

The seeding device flag can be cleared again by btrfstune -f -S 0, e.g. allowing to update with newer data but please note that this will invalidate all existing filesystems that use this particular seeding device. This works for some use cases, not for others, and the forcing flag to the command is mandatory to avoid accidental mistakes.
可以通过 btrfstune -f -S 0 再次清除种子设备标志,例如,允许使用更新的数据,但请注意,这将使使用此特定种子设备的所有现有文件系统无效。这适用于某些用例,但不适用于其他用例,并且命令的强制标志是必需的,以避免意外错误。

Example how to create and use one seeding device:
创建和使用一个种子设备的示例:

# mkfs.btrfs /dev/sda
# mount /dev/sda /mnt/mnt1
... fill mnt1 with data
# umount /mnt/mnt1

# btrfstune -S 1 /dev/sda

# mount /dev/sda /mnt/mnt1
# btrfs device add /dev/sdb /mnt/mnt1
# umount /mnt/mnt1
# mount /dev/sdb /mnt/mnt1
... /mnt/mnt1 is now writable

Now /mnt/mnt1 can be used normally. The device /dev/sda can be mounted again with a another writable device:
现在 /mnt/mnt1 可以正常使用。设备 /dev/sda 可以再次与另一个可写设备挂载:

# mount /dev/sda /mnt/mnt2
# btrfs device add /dev/sdc /mnt/mnt2
# umount /mnt/mnt2
# mount /dev/sdc /mnt/mnt2
... /mnt/mnt2 is now writable

The writable device (file:/dev/sdb) can be decoupled from the seeding device and used independently:
可以将可写设备(文件:/dev/sdb)与种子设备分离,独立使用:

# btrfs device delete /dev/sda /mnt/mnt1

As the contents originated in the seeding device, it’s possible to turn /dev/sdb to a seeding device again and repeat the whole process.
由于内容源自种子设备,可以将 /dev/sdb 再次转换为种子设备,重复整个过程。

A few things to note:
一些需要注意的事项:

  • it’s recommended to use only single device for the seeding device, it works for multiple devices but the single profile must be used in order to make the seeding device deletion work
    建议只使用单个设备作为种子设备,虽然多个设备也可以使用,但必须使用单个配置文件才能使种子设备删除功能正常工作

  • block group profiles single and dup support the use cases above
    区块组配置文件 single 和 dup 支持上述用例

  • the label is copied from the seeding device and can be changed by btrfs filesystem label
    标签是从种子设备复制的,并可以通过 btrfs 文件系统标签进行更改

  • each new mount of the seeding device gets a new random UUID
    每次挂载种子设备时都会获得一个新的随机 UUID

  • umount /path; mount /dev/writable /path can be replaced with mount -o remount,rw /path but it won’t reclaim space of deleted subvolumes until the seeding device is mounted read-write again before making it seeding again
    umount /path; mount /dev/writable /path 可以替换为 mount -o remount,rw /path,但在将种子设备再次挂载为读写模式之前,它不会回收已删除子卷的空间,然后再次将其设置为种子设备

Chained seeding devices
链式播种设备

Though it’s not recommended and is rather an obscure and untested use case, chaining seeding devices is possible. In the first example, the writable device /dev/sdb can be turned onto another seeding device again, depending on the unchanged seeding device /dev/sda. Then using /dev/sdb as the primary seeding device it can be extended with another writable device, say /dev/sdd, and it continues as before as a simple tree structure on devices.
虽然不建议这样做,而且这是一个相当模糊且未经测试的用例,但是可以链接播种设备。在第一个示例中,可写设备 /dev/sdb 可以再次转到另一个播种设备,取决于未更改的播种设备 /dev/sda 。然后,使用 /dev/sdb 作为主要播种设备,可以使用另一个可写设备 /dev/sdd 进行扩展,然后继续作为设备上的简单树结构。

# mkfs.btrfs /dev/sda
# mount /dev/sda /mnt/mnt1
... fill mnt1 with data
# umount /mnt/mnt1

# btrfstune -S 1 /dev/sda

# mount /dev/sda /mnt/mnt1
# btrfs device add /dev/sdb /mnt/mnt1
# mount -o remount,rw /mnt/mnt1
... /mnt/mnt1 is now writable
# umount /mnt/mnt1

# btrfstune -S 1 /dev/sdb

# mount /dev/sdb /mnt/mnt1
# btrfs device add /dev/sdc /mnt
# mount -o remount,rw /mnt/mnt1
... /mnt/mnt1 is now writable
# umount /mnt/mnt1

As a result we have:
因此,我们有:

  • sda is a single seeding device, with its initial contents
    sda 是一个单个的播种设备,具有其初始内容

  • sdb is a seeding device but requires sda, the contents are from the time when sdb is made seeding, i.e. contents of sda with any later changes
    sdb 是一个播种设备,但需要 sda,其内容来自于 sdb 成为播种设备时的时间,即 sda 的内容以及任何后续更改

  • sdc last writable, can be made a seeding one the same way as was sdb, preserving its contents and depending on sda and sdb
    sdc 最后可写,可以像 sdb 一样制作成播种设备,保留其内容并依赖于 sda 和 sdb

As long as the seeding devices are unmodified and available, they can be used to start another branch.
只要播种设备未经修改且可用,它们就可以用来启动另一个分支。