LWN:使用blksnap抓取块设备的快照!
Block-device snapshots with blksnapBy Jonathan CorbetNovember 14, 2022DeepL assisted translationhttps://lwn.net/Articles/914031/一般来说在技术领域内只要工作过一段时间就能清楚地意识到多么需要良好的数据备份习惯。但是如果在备份过程中相关的文件系统正在频繁地变动那么很难创建出一个真正完好的备份。多年来已经开发出各种方法来解决这个问题比如在备份运行时直接关闭系统或者各种快照机制。如果 Sergei Shtepa 的 blksnap patch set 能进入 mainline 的话那么内核可能会得到另一种快照方案。blksnap patch完全没有文档所以下面的内容大部分来自于对代码的分析理解也就是纯逆向工程得出的。Blksnap 是在 block 设备层来进行快照这意味着相关设备上的任何文件系统都是完全可以透明地支持起来的。它能够将多个块设备组合起来创建出快照所以它应该会很适用于 RAID 阵列之类的情况。目标使用场景可能是那些自动备份系统blksnap 创建的快照被称为 non-persistent只要真正进行了备份之后就会将其丢弃掉。由于 blksnap 是在 block 层实现的所以它必须需要一个不属于被抓取快照的设备上的空间来存储快照文件。具体来说可以用一些 ioctl()操作来从另一个设备上分配出一些扇区用来存储 difference blocks差异数据块并随着时间推移会修改分配了哪些扇区。并且具备通知机制当某个存放差异数据区域空间不足时用户空间进程可以收到通知从而可以继续为该区域分配更多的 block。blksnap 使用的算法非常简单一旦为一组块设备创建了快照通过另一个 ioctl()操作来发起blksnap 就会拦截对这些设备中每一个 block 进行的写入操作。如果某个 block 在快照之后第一次被写入那么该 block 上之前的内容就会被复制到差异数据区域并且会记录下该 block 在快照创建好后被改变的情况。这样做了之后写操作就可以继续正常进行了。因此block device 上的数据总是可以展示最近写入之后的情况而差异数据区则包含了快照创建时的这些较早数据从而可以用来根据快照恢复状态。为了能够拦截这些对 block 设备的写入操作Shtepa 不得不在 block 层添加了一个新的 device filter 机制。可以给某个设备来附加一个 filter从而在该设备上的每个操作执行之前都被调用使用代表这个操作的 BIO 结构来当作 filter 的一个参数。如果 filter 函数返回了 false这个操作就不会被执行。早期版本的 patch set 中提供了将多个 filter 附加到同一个 block 设备上的不同 位置 的功能但由于目前 filter 还没有其他用途所有这部分功能被删除了。Blksnap 使用 filter 功能来捕捉对抓取了快照的设备的写操作。当发现有写操作时就会暂停这个操作同时将要写的 block 的原始内容复制到差异数据区在完成之后才会正常提交这个写操作。有趣的是这组 patch set 中没有任何地方描述在快照被创建之后人们如何访问到它。不过看看 ioctl()接口就可以猜到几种可能性。其一是获取与 snapshot 相关的有过改动的 block 列表这对于某些类型的增量备份场景来说可能很有用。但 blksnap 也为每个快照都创建了一个新的、只读的设备。从该设备中读取一个 block 就会让 blksnap 查询它内部维护的有过改动的 block 的 map如果相关的 block 已经被变更过那么它就会从差异数据区中来读取。否则的话就直接从原始 block 设备中读取。快照设备的 major number 和 minor number 可以通过另一个 ioctl() 操作来获得还有一个没有文档描述的 sysfs 文件可以用来参考。内核现在并不缺乏制作快照的功能所以人们可能会顺理成章地问为什么还需要 blksnap。它显然跟 Btrfs 等文件系统所提供的快照功能不一样因为 blksnap 是在 block 设备层来实现的。所以 blktrace 可以用在那些本身没有快照功能的文件系统上。Btrfs 的快照与文件系统本身都是存放在同一个块设备上的这意味着两者会互相争抢存储空间而快照所使用的空间可能会阻止像当前活跃的文件系统中写入数据。由于 blksnap 将其快照数据存储在一个单独的设备上所以这些数据不会妨碍正在进行的操作。在差异数据区的空间用完了的情况下快照就会被破坏但被快照的设备本身并不会受到影响。在块设备层还存在一个现成的替代方案就是 device mapper snapshot target。blksnap 提供的功能跟它在很多方面都比较相似两者都是通过拦截写操作并将旧数据复制到另一个独立的设备上来实现的。不过Blksnap 并不需要给要被快照的设备设置 device mapper。它还声称对其差异数据区实现了更灵活的管理尤其是当有多个设备一起被快照的时候。这些差异似乎已经足够了所以到目前为止没看到有人质疑 blksnap 是否有必要添加到内核里。该 patch set尽管被标记为 v1正在进行从 7 月的第一次发布之后进行的第二次修改其中已经包含了不少 fix。运气好的话下一次修订没准能让我们看到一些文档然后可能就差不多准备好可以被纳入 mainline 了。全文完LWN 文章遵循 CC BY-SA 4.0 许可协议。