Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/live-snapshot.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,21 @@ The new config file should include the current upper layer as the last lower lay
```

**Note**: The new upper layer must be different from the old upper layer.

`lowers` is the old list plus one entry: the (N+1)-th lower is the old upper data file, sealed. Where that layer ends up is decided by its `file`: the current `upper.data` keeps it in place, while any other absolute path moves it there as part of the snapshot. A move requires the target to be absent and on the same file system as the data file; missing parent directories are created.

The first N entries must match the old lowers exactly. The old upper's `upper.index` is not referenced after the snapshot and can be deleted by the caller.

## Failure Semantics and Crash Recovery

Updating the config is the commit point. A failure before it returns -1, removes the transaction files and leaves the layers untouched, so the request can be retried right away; after it, only in-memory operations remain. A request that describes the stack already committed returns success, and the caller's config file is left as is.

Two transaction files live next to the config: `.snapshot` holds the new config bytes, so its presence means the snapshot is uncommitted; `.snapshot.undo` holds the move target and exists only for a move. If the snapshot is uncommitted, the sealed layer is moved back as `.undo` records and both files are cleaned up; if it is committed, only a stale `.undo` is removed. Recovery covers process crashes only; a host power loss is out of scope.

A failed seal needs no rollback: it only appends, leaving an unreachable index and trailer at the end of the data file, and since the header is untouched the device still opens after a restart. Sparse writable layers are the exception: their mappings are rebuilt by scanning the data file, so the file is truncated to `virtual_size` when opened.

## Limitations

- Snapshots are not supported with a warpfile upper layer (`upper.target`).
- With a hybrid or sparse upper, writes do not take the snapshot's write lock, so the caller must pause writes while a snapshot runs.
- Snapshots on one device are serialized; a running snapshot holds the device's write path.
18 changes: 17 additions & 1 deletion docs/live-snapshot_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,20 @@ curl -X POST "http://127.0.0.1:9862/snapshot?dev_id=123&config=/path/to/new_conf
}
```

**注意**:新的 upper 层必须与旧的 upper 层不同。
lowers 由旧的 lowers 追加一层构成:第 N+1 个 lower 是旧 upper 的 data 文件经 seal 得到,其 `file` 等于当前 `upper.data` 时原地 seal;为其它绝对路径时,seal 后把 data 文件 rename 到该路径,要求目标不存在、与 data 文件同文件系统,父目录缺失时自动创建。

前 N 项与旧的 lowers 逐字段一致,upper 必须与旧的 upper 不同。旧 upper 的 `upper.index` 快照后不再被引用,可由调用方清理。

## 失败语义与崩溃恢复

提交点是更新 config:之前失败返回 -1、清理事务文件,层结构不变,可立即重试;之后只剩内存操作。描述已提交层结构的请求直接返回成功,调用方传入的 config 不会被消费。

config 旁有两个事务文件:`.snapshot`(待更新的 config 字节,存在即未提交)与 `.snapshot.undo`(改名目标,仅改名时存在)。未提交时先按 `.undo` 把 sealed 层移回原路径,再清理两个文件;已提交时只清理残留的 `.undo`。恢复只覆盖进程崩溃(kill、异常退出),主机掉电不在保证范围内。

seal 失败处理:seal 只追加写,data 尾部仅留下不可达的 index 与 trailer,header 未变,重启后的设备仍可打开,因此不需要回滚。稀疏可写层例外:其映射靠扫描 data 文件重建,因此打开时需要按 `virtual_size` 截断。

## 限制

- upper 为 warpfile(`upper.target`)时,不支持快照。
- upper 为 hybrid 或 sparse 时,写路径不持快照使用的写锁,快照期间需调用方暂停写入。
- 同一设备的快照串行执行;快照期间设备的写路径被占用。
Loading
Loading