Skip to main content

Crate pmbs

Crate pmbs 

Source
Expand description

§胖喵必快 (pmbs) 主要设计文档

胖喵必快 (pmbs)

正式名称: 紫腹巨蚊 (Toxorhynchites gravelyi) 系列
    澳大利亚海神草 (Posidonia australis) 软件

目录:

  • 1 问题背景

  • 2 源代码目录结构

  • 3 命令行环境变量

  • 4 快照目录结构

  • 5 systemd timer

  • 6 自动清理

§1 问题背景

本软件的主要设计用途是 防误删. 也就是不小心删除自己的重要文件, 造成数据丢失.

典型的 定期备份 (backup) 是不够的, 因为间隔时间通常较长, 比如每周或每天备份一次. 实时同步 (sync) 文件 (比如给一个目录设置镜像) 也是不够的, 因为原文件被删除之后, 镜像也会被同步删除.

快照 (snapshot) 是一个很好的解决方案, 特别是 btrfs 快照. 因为 btrfs 的 CoW (写时复制) 特性, 快照是轻量级, 快速的. 只有快照后变动的文件, 才会占用额外的存储空间. 通过使用 root 创建 只读 快照, 普通用户无权限删除快照 (只能读取), 从而可以在很大程度上防止误删除. 如果发生了误删, 普通用户可以直接读取之前的快照, 恢复文件 (复制回来), 恢复过程无需 root, 进一步降低了风险 (避免误操作破坏快照, 导致数据彻底丢失).

snapper (http://snapper.io/) 是一个现有的自动 btrfs 快照开源软件, 本来考虑的就是直接使用 snapper. 然而 snapper 只支持 每小时 快照一次, 间隔时间太长了. 对窝来说, 丢失最近一小时的数据是不可接受的. 因此, 只能自己再写一个软件了, 目标是实现 分钟级 快照 (Per Minute Btrfs Snapshot), 如果不小心发生了误删, 数据丢失通常在 1 分钟以内, 这是可以接受的.

注意, 快照 不能替代备份 !! 如果发生 硬件损坏 (比如磁盘故障), 操作系统 BUG (比如 Linux 内核, btrfs 文件系统的 BUG) 等情况, 仍然会发生数据丢失损坏, 快照对此无能为力.


根据上述使用场景, 只读快照需要以 root 在后台定期自动创建. root 是 Linux 系统中的超级用户权限, 如果出问题可能造成严重的破坏, 因此必须谨慎使用.

所以选择使用 rust (https://www.rust-lang.org/) 编程语言来编写本软件, 避免使用 unsafe, 同时尽量保持代码和功能的简单 (简单的东西更不容易出 BUG).

创建快照 (删除快照) 功能, 实现方法是直接调用 btrfs 命令行, 比如 btrfs subvol snapshot -rbtrfs subvol delete.

定期执行功能, 使用 systemd timer 触发 (https://wiki.archlinux.org/title/Systemd). 因为 systemd 是 Linux 系统的关键基础系统组件 (PID 1), 所以稳定性应该是很高的, 不容易出问题.

大量快照会占用大量的存储空间, 因此 自动清理 功能也是很重要的, 根据配置自动删除旧的快照.

注意: 目前本软件 不会检测剩余存储空间, 存在耗尽存储空间的风险, 需要多关注, 经常查看剩余存储空间. 因为本软件认为, 相比耗尽存储空间的风险, 数据丢失是更严重的情况, 更不能接受, 因此及时创建新的快照是更优先的事情.

§2 源代码目录结构

  • src/: 本软件的源代码 (rust).

  • doc/: 文档.

  • systemd-unit/: systemd 服务文件, 用于实现 systemd timer.

  • etc-pmbs/: 配置文件示例.

  • build-aur/: 用于构建 ArchLinux 软件包 (含有 AUR 的 PKGBUILD).

  • build-rpm/: 用于构建 RPM 软件包 (用于 Fedora CoreOS).

  • .github/: CI (自动化测试编译).

§3 命令行环境变量

本软件的命令行参数是很简单的, 这可以简化解析命令行的代码. 更多配置选项通过 环境变量 (env var) 实现.

config::ConfigEnv 定义了所有使用的环境变量:

环境变量默认值说明
PMBS_DIR_ETC/etc/pmbs存放配置文件 (*.toml) 的目录
PMBS_DIR_LOG/var/log/pmbs写入日志文件的目录
PMBS_BIN_BTRFSbtrfsbtrfs 命令
RUST_LOGinfo输出日志级别 (env_logger)

§4 快照目录结构

比如:

> ls -ali .pmbs
总计 4
929570 drwxr-xr-x 1 root root   20  9月 2日 03:48 ./
   256 drwxr-xr-x 1 root root   54  8月28日 23:32 ../
929571 drwxr-xr-x 1 root root 4080  9月 2日 03:48 2025/
944869 lrwxrwxrwx 1 root root   15  9月 2日 03:48 latest -> 2025/1756756128/
> ls -ali .pmbs/2025

   256 drwxr-xr-x 1 root root   54  8月28日 23:32 1756756005/
   256 drwxr-xr-x 1 root root   54  8月28日 23:32 1756756066/
   256 drwxr-xr-x 1 root root   54  8月28日 23:32 1756756128/
  • 在目标 subvol (被快照的 subvol) 之下直接创建 .pmbs 目录, 比如 /home/.pmbs

  • 快照 (snapshot) 路径类似 .pmbs/2025/1756756128/

    其中 1756756128 是时间戳 (UNIX_EPOCH 开始的秒数), 2025 是对应的年.

  • 符号链接 .pmbs/latest 指向最新的快照.

§5 systemd timer

有 2 个 systemd timer (以及对应的 service):

  • pmbs-snapshot.timer (pmbs-snapshot.service) 定期执行:

    pmbs config snapshot

    读取所有配置文件, 并创建对应的快照.

    每分钟 (60 秒) 执行一次, 时间精度 1 秒, 随机延迟 1 秒.

  • pmbs-clean.timer (pmbs-clean.service) 定期执行:

    pmbs config clean

    读取所有配置文件, 并执行自动清理.

    每 10 分钟执行一次, 时间精度 1 分钟, 随机延迟 1 分钟.

§6 自动清理

TODO

Modules§

clean
自动清理
cli
命令行相关处理
config
配置文件读取和处理
snapshot
创建 btrfs 快照