跳到主要内容

ws-ckpt IPC 协议

概述

cosh-ng 通过 Unix Domain Socket 与 ws-ckpt 守护进程通信,实现工作空间快照管理。 通信使用 bincode 序列化 + 4 字节小端长度前缀 的帧格式。

架构

cosh-cli / cosh-core ws-ckpt daemon
│ │
│ Unix socket │
│ /run/ws-ckpt/ws-ckpt.sock │
│─────────────────────────────→│
│ [4B LE len][bincode req] │
│ │
│←─────────────────────────────│
│ [4B LE len][bincode resp] │

客户端实现位于 crates/cosh-platform/src/checkpoint.rsCkptClient), 类型定义位于 crates/cosh-types/src/checkpoint.rs

帧格式

每个消息由两部分组成:

┌──────────────────┬───────────────────────────────┐
│ 4 字节 LE u32 │ bincode 编码的枚举载荷 │
│ (payload 长度) │ (WsCkptRequest / Response) │
└──────────────────┴───────────────────────────────┘
  • 长度前缀:小端序无符号 32 位整数,表示后续 bincode 载荷的字节数
  • 最大响应限制:64 MiB(防止 OOM)
  • 默认超时:5000ms(可通过 CkptClient::with_timeout() 配置)

请求类型(WsCkptRequest)

bincode 按枚举变体索引序列化(第一个变体 = index 0)。变体顺序即二进制契约,不可重排。

索引变体说明
0Init { workspace }初始化工作空间
1Checkpoint { workspace, id, message, metadata, pin }创建快照
2Rollback { workspace, to }回滚到指定快照
3Delete { workspace, snapshot, force }删除快照
4List { workspace, format }列出快照
5Diff { workspace, from, to }两个快照间的差异
6Status { workspace }查询状态
7Cleanup { workspace, keep }清理旧快照
8Config获取守护进程配置
9ReloadConfig重新加载配置
10Recover { workspace }恢复工作空间
11HealthAdvisory健康检查

响应类型(WsCkptResponse)

变体对应请求关键字段
InitOk { ws_id }Init工作空间 ID
CheckpointOk { snapshot_id }Checkpoint快照 ID
RollbackOk { from, to }Rollback回滚源和目标
DeleteOk { target }Delete被删除的快照标识
Error { code, message }任意错误码 + 人类可读描述
ListOk { snapshots }ListVec<SnapshotEntry>
DiffOk { changes }DiffVec<DiffEntry>
StatusOk { report }StatusStatusReport
CleanupOk { removed }Cleanup被移除的快照 ID 列表
ConfigOk { config }ConfigConfigReport
ReloadConfigOkReloadConfig无载荷
CheckpointSkipped { reason }Checkpoint跳过原因(如无变更)
RecoverOk { workspace }Recover恢复的工作空间路径
HealthAdvisoryOk { ... }HealthAdvisory超限工作空间数、磁盘用量

错误码(WsCkptErrorCode)

索引变体说明
0WorkspaceNotFound工作空间不存在
1SnapshotNotFound快照不存在
2AlreadyInitialized工作空间已初始化
3BtrfsErrorBtrfs 操作错误
4IoErrorI/O 错误
5InvalidPath非法路径
6ConfirmationRequired需要确认(如删除 pinned 快照)
7InternalError内部错误
8SnapshotAlreadyExists快照 ID 冲突
9WriteLockConflict写锁冲突
10DiskSpaceInsufficient磁盘空间不足

客户端使用

use cosh_platform::checkpoint::CkptClient;

// 默认路径 /run/ws-ckpt/ws-ckpt.sock
let client = CkptClient::default_path();

// 或指定路径和超时
let client = CkptClient::with_timeout("/custom/path.sock", 10000);

// 健康检查
if !client.is_available() {
eprintln!("ws-ckpt daemon not running");
}

// 操作示例
let result = client.create("/home/user/project", "snap-001", Some("initial"), None, false)?;
let list = client.list(Some("/home/user/project"))?;
let restored = client.restore("/home/user/project", "snap-001")?;

关键约束

约束说明
变体顺序不可变bincode 使用索引序列化枚举,重排即破坏线格式
新增只能追加新的 Request/Response 变体只能在末尾添加
类型必须同步cosh-types 中的定义必须与 ws-ckpt-common 完全一致
超时处理客户端对 read/write 设置超时,避免守护进程无响应时阻塞
长度限制响应超过 64 MiB 视为异常,立即断开
socket 路径默认 /run/ws-ckpt/ws-ckpt.sock,可通过环境变量或 CLI 参数覆盖

测试验证

cd src/cosh-ng

# bincode 往返序列化测试
cargo test --locked -p cosh-types -- checkpoint

# 变体索引契约测试
cargo test --locked -p cosh-types test_request_bincode_variant_index

# CkptClient 单元测试(不需要运行的守护进程)
cargo test --locked -p cosh-platform -- checkpoint