feat(chv): 阶段 1 数据盘与 tenant 标记同 overlay 解耦(copy 也供)
真机根因(2026-11-07,CHV v54 三变体实证):vm.boot 对任何 带 backing file 的 qcow2 都报 Maximum disk nesting depth exceeded——overlay-only 与 overlay-rawbase 均 500,base 直接 启动(reuse)22.5 秒成功,数据盘与压缩均已排除。overlay 在 本 VMM 上不可用,持久 VM 须能在 copy 模式下跑。 - _provision_task_disk:copy 与 overlay 都供数据盘并写 tenant.json(只有 reuse 不供不写);_provision_data_disk_path 同理(reuse 才返回 None)。 - _cleanup_vm_task_disk:保护(持久登记/登记快照)不再只限 overlay 模式;无登记无快照的 copy 盘仍按旧语义删除。 - provision_data_disk:数据盘改 raw 稀疏盘(os.truncate, 零外部依赖)——copy 模式本来就不需要 qemu-img,数据盘 绝不能悄悄加上这个依赖;CHV 按后缀认 Raw。 - 测试:新增 copy 供数据盘+tenant 与 copy 持久盘 stop 保护; VmConfig 三盘断言(任务+seed+数据)更新 arch95/fix 两处 旧“恰好两盘”契约与本轨 qcow2 类型断言。 回归:test_chv_*.py、test_cloud_hypervisor.py 42、test_chv_v3_fixes 38 全过(全量 cloud/tests 在跑)。 不推、不合、不部署;只本地分支。
This commit is contained in:
1 parent
a5f836e9fd
commit
f809014bef
5 files changed
+113
-65
No files matched your search
+27
-20
@@ -1397,25 +1397,32 @@ class CloudHypervisorExecutor(Executor):
|
||||
放行,见 preflight,feat-chv-fix)。
|
||||
- overlay(feat-chv-opt-landing,阶段 1):在
|
||||
state_dir/<vm>/disk.qcow2 建空 overlay,backing
|
||||
file 指向只读 base;同时供给独立数据盘
|
||||
state_dir/<vm>/data.qcow2(工作区/浏览器 profile
|
||||
载体,不进快照);供给后写 tenant 归属标记
|
||||
tenant.json(reuse 不写——盘就是共享 base,标给
|
||||
某租户是错的)。
|
||||
file 指向只读 base。
|
||||
数据盘与 tenant 标记与 overlay 解耦(2026-11-07 真机
|
||||
实测:CHV v54 的 vm.boot 对任何带 backing file 的
|
||||
qcow2 都报 Maximum disk nesting depth exceeded,
|
||||
overlay 在本 VMM 上不可用——见阶段 1 报告 §overlay;
|
||||
但数据盘(工作区/浏览器 profile 载体,不进快照)与
|
||||
tenant.json(持久 VM 归属)是独立持久/归属机制,
|
||||
不依赖 backing file):copy 与 overlay 都供给独立
|
||||
数据盘 state_dir/<vm>/data.raw 并写 tenant 归属
|
||||
标记 tenant.json;只有 reuse 不写(盘就是共享 base,
|
||||
标给某租户是错的)。
|
||||
返回每任务磁盘路径。"""
|
||||
disk = provision_task_disk(
|
||||
self.state_dir, self.vm_name(task), self.rootfs,
|
||||
self.disk_mode)
|
||||
if getattr(self, "disk_mode", "copy") == "overlay":
|
||||
if getattr(self, "disk_mode", "copy") in ("overlay", "copy"):
|
||||
provision_data_disk(self.state_dir, self.vm_name(task))
|
||||
write_vm_tenant(self.state_dir, self.vm_name(task),
|
||||
self._tenant_id(task), disk=disk)
|
||||
return disk
|
||||
|
||||
def _provision_data_disk_path(self, task):
|
||||
"""overlay 模式的数据盘路径(VmConfig 第三块盘):
|
||||
非 overlay 模式即 None(不挂数据盘,行为与旧版一致)。"""
|
||||
if getattr(self, "disk_mode", "copy") != "overlay":
|
||||
"""数据盘路径(VmConfig 第三块盘):copy 与 overlay 都
|
||||
挂(见 _provision_task_disk 的解耦说明);只有 reuse
|
||||
返回 None(共享 base,不挂私有数据盘)。"""
|
||||
if getattr(self, "disk_mode", "copy") == "reuse":
|
||||
return None
|
||||
return data_disk_path(self.state_dir, self.vm_name(task))
|
||||
|
||||
@@ -2740,12 +2747,11 @@ class CloudHypervisorExecutor(Executor):
|
||||
return None
|
||||
|
||||
def _overlay_disk_protected(self, name) -> bool:
|
||||
"""该 VM 的 overlay 盘是否受保护(stop/GC 不删):
|
||||
"""该 VM 的任务盘是否受保护(stop/GC 不删):
|
||||
有持久登记认领,或有登记快照(hibernate 的 restore
|
||||
输入)。copy 模式的 disk.raw 不受此保护(旧语义,
|
||||
_cleanup_vm_files 只在 overlay 模式下查它——见下),
|
||||
但本方法本身不分模式,调用方按模式决定是否查。
|
||||
数据盘 data.qcow2 永远不受 GC/stop 删除(另有显式
|
||||
输入)。不分模式(2026-11-07:copy 模式也要能跑持
|
||||
久 VM;无登记/无快照的盘仍按旧语义删除)。
|
||||
数据盘 data.raw 永远不受 GC/stop 删除(另有显式
|
||||
回收入口),本方法不覆盖它。"""
|
||||
if self._persistent_record_for_vm(name) is not None:
|
||||
return True
|
||||
@@ -2753,11 +2759,12 @@ class CloudHypervisorExecutor(Executor):
|
||||
|
||||
def _cleanup_vm_task_disk(self, name, task, keep_disk) -> bool:
|
||||
"""stop 的任务盘删除块(_cleanup_vm_files 的中段):
|
||||
keep_disk 或 overlay 受保护盘(持久登记认领/有登记
|
||||
快照)即跳过;删掉返回 False(无失败),删失败记
|
||||
审计并返回 True(脏标记由调用方写)。"""
|
||||
_protected = getattr(self, "disk_mode", "copy") == "overlay" \
|
||||
and self._overlay_disk_protected(name)
|
||||
keep_disk 或受保护盘(持久登记认领/有登记快照)即
|
||||
跳过;删掉返回 False(无失败),删失败记审计并返回
|
||||
True(脏标记由调用方写)。保护不分模式(2026-11-07:
|
||||
copy 模式也要能跑持久 VM;无登记/无快照的 copy 盘
|
||||
仍按旧语义删除,只有被认领/被快照引用的盘才留)。"""
|
||||
_protected = self._overlay_disk_protected(name)
|
||||
try:
|
||||
if not keep_disk and not _protected \
|
||||
and delete_task_disk(self.state_dir, name):
|
||||
@@ -2900,7 +2907,7 @@ class CloudHypervisorExecutor(Executor):
|
||||
feat-chv-v3:有登记快照的 VM 不 GC 盘——那是休眠
|
||||
VM 的盘,restore 还要读它(见 hibernate_vm)。
|
||||
feat-chv-opt-landing:有持久登记认领的 VM 同样不
|
||||
GC(那是用户的持久盘);数据盘 data.qcow2 永不进
|
||||
GC(那是用户的持久盘);数据盘 data.raw 永不进
|
||||
GC(用户数据,只走显式回收 recycle_persistent_vm)。"""
|
||||
deleted: list = []
|
||||
failed: list = []
|
||||
|
||||
Reference in new issue
Block a user