删快照前必看!VirtualBox 报错 E_FAIL 的终极解决方案

52 阅读9分钟

【踩坑系列2】删快照前必看!VirtualBox 报错 E_FAIL 的终极解决方案

提示:文中有完整命令速查,建议收藏备用,关键时刻能救急!


📖 开篇:我差点把虚拟机删了

事情是这样的。

我的 Ubuntu 虚拟机磁盘空间告急,原本分配的 50GB 已经用了 40GB+,再这样下去连环境都搭不起来了。

于是我决定:扩容到 100GB。

看起来很简单对吧?VirtualBox 官方文档写得明明白白:

<h1>1. 扩容虚拟硬盘</h1>
VBoxManage modifymedium "Ubuntu.vdi" --resize 102400
<h1>2. 进入系统扩展分区</h1>
sudo growpart /dev/sda 2
sudo resize2fs /dev/sda2

但现实给了我一记响亮的耳光。

扩容命令执行成功了,但进入系统后 df -h 显示的还是 50G!

我心态崩了。


🔍 排查一小时,发现罪魁祸首是"快照"

经过一番搜索,我发现问题出在快照上。

打开 VirtualBox 的虚拟介质管理器,我看到了这样的结构:

Ubuntu.vdi (基础盘)
├── 快照:202603101718 (父快照)
│   ├── 快照:备份 4 (子快照)
│   └── 快照:备份 5 (子快照)

这是一个树状快照链,不是线性链!

这意味着:

  • 基础盘 Ubuntu.vdi 被两个子快照同时引用

  • 直接扩容基础盘,快照链会断裂

  • VirtualBox 为了保护数据,阻止了扩容操作

解决方案很简单:删除快照,然后扩容。

但接下来发生的事情,让我彻底崩溃。


💥 删除快照,弹出 E_FAIL 错误

我打开命令行,执行删除快照命令:

C:\Program Files\Oracle\VirtualBox>VBoxManage snapshot "Ubuntu-zhou" delete "274265cf-8dc8-4d34-803f-9cb788895635"
Deleting snapshot '备份 5'
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
✅ 成功



C:\Program Files\Oracle\VirtualBox>VBoxManage snapshot "Ubuntu-zhou" delete "c15a53b5-12f1-4226-a062-e24e07c3bbf8"
Deleting snapshot '备份 4'
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
✅ 成功





C:\Program Files\Oracle\VirtualBox>VBoxManage snapshot "Ubuntu-zhou" delete "62f3ebe6-1c31-4afb-8afe-1a97076956da"
Deleting snapshot '202603101718'
0%...E_FAIL
❌ 失败!

错误信息:

VBoxManage.exe: error: Hard disk 'D:\VirtualBox\Ubuntu-zhou\Ubuntu.vdi' 
has more than one child hard disk (2)
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), 
component SessionMachine, interface IMachine

翻译成人话:

你的硬盘 Ubuntu.vdi 有两个子硬盘引用,直接删除父快照会导致数据结构混乱,为了保护数据,我拒绝操作。

我当时的心态:

😤😤😤

🛠️ 尝试 5 种方案,4 种都失败了

方案 1:图形界面删除(❌ 失败)

我打开 VirtualBox 图形界面,找到快照管理器:

VirtualBox → 控制 → 快照

问题:右键只有"删除"选项,点击后依然报 E_FAIL 错误!

而且根本没有教程里说的"合并到当前状态"选项!

方案 2:导出/导入虚拟机(❌ 太慢)

有教程说可以导出为 OVA 格式再导入,这样会合并所有快照。

但我估算了一下时间:

  • 导出:5~10 分钟

  • 导入:5~10 分钟

  • 还要重新配置网络、共享文件夹等设置

太麻烦了,而且我急着用虚拟机,等不了!

方案 3:直接删除快照文件(❌ 危险!)

有"野路子"说可以直接进入 Snapshots 文件夹删除里面的 .vdi 文件。

但我立刻否定了这个方案:

⚠️ 警告:直接删除快照文件会导致虚拟机无法启动!

因为 VirtualBox 的快照是差分存储:

  • Ubuntu.vdi 是基底硬盘(可能只有几 G)

  • Snapshots 里的文件是"增量包",记录每次修改的新增数据

  • 直接删除快照文件,虚拟机就找不到增量包了,启动时会崩溃

这个险我不能冒,里面有我几天的工作成果!

方案 4:网上找的"强制合并"命令(❌ 不适用)

VBoxManage modifyhd "Ubuntu.vdi" --mergehd <快照 UUID>

执行后提示:操作不支持

这个命令对快照链结构有严格要求,只适用于线性快照链,对于树状快照链无效。

方案 5:克隆虚拟机(✅ 成功!)

就在我准备放弃的时候,我看到了一个不起眼的评论:

"快照链太复杂的话,直接用 clonevm 克隆当前状态,新生成的虚拟机没有快照。"

我抱着试一试的心态执行了命令...

然后奇迹发生了!


✅ 终极解决方案:克隆虚拟机

操作步骤(亲测有效)

1. 确保虚拟机处于"当前状态"

<h1>启动 Ubuntu,确认桌面文件、软件都在</h1>
<h1>然后正常关机(不要休眠)</h1>

2. 执行克隆命令

cd "C:\Program Files\Oracle\VirtualBox"



VBoxManage clonevm "Ubuntu-zhou" --name "Ubuntu-Clean" --basefolder "D:\VirtualBox" --register

参数说明:

  • "Ubuntu-zhou":原虚拟机名字

  • "Ubuntu-Clean":新虚拟机名字(随便起)

  • --basefolder "D:\VirtualBox":新虚拟机存放路径

  • --register:注册到 VirtualBox 列表,这样就能在界面上看到它

3. 等待克隆完成

0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
✅ 克隆成功!

克隆完成后,新虚拟机 Ubuntu-Clean 是一个干净的单一硬盘,没有任何快照链!

那一刻,我差点哭出来。


🎯 扩容操作(现在可以顺利执行了)

6.1 扩容虚拟硬盘

1. 关闭 Ubuntu-Clean 虚拟机

⚠️ 必须完全关机,不能休眠或保存状态

2. 执行扩容命令

cd "C:\Program Files\Oracle\VirtualBox"



VBoxManage modifymedium "D:\VirtualBox\Ubuntu-Clean\Ubuntu-Clean-disk1.vdi" --resize 102400

⚠️ 注意:

  • 路径必须是新克隆的 .vdi 文件(我的文件名是 Ubuntu-Clean-disk1.vdi

  • 102400 = 100GB(100 × 1024 = 102400 MB)

3. 等待进度条完成

Progress: 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
✅ 硬盘扩容完成!

6.2 在 Ubuntu 内部扩展分区

这时候还没完!  进度条到 100% 只是硬件层面扩容完成,系统内部还是 50G。

1. 启动 Ubuntu-Clean,打开终端

2. 扩展分区表

sudo growpart /dev/sda 2

输出:

CHANGED: partition=2 start=4096 old: size=104851456 end=104855551 
new: size=209711071 end=209715166

这说明分区 2(/dev/sda2)已经从约 50G 扩大到约 100G!

3. 扩展文件系统

sudo resize2fs /dev/sda2

输出:

resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old desc blocks = 13107200, new desc blocks = 26214400
The filesystem on /dev/sda2 is now 26213884 blocks (each 4096 bytes).

4. 验证结果

df -h

输出:

文件系统        容量  已用  可用  已用%  挂载点
/dev/sda2        99G   43G   51G   46%   /

🎉 99G ≈ 100G,扩容彻底成功!

那一刻,我真的想哭出来。

**
**

关键概念:动态分配磁盘

VirtualBox 的 VDI 文件有两种类型:

类型特点适用场景
动态分配按需增长,初始很小,随使用逐渐变大节省空间,推荐
固定大小创建时就占用全部空间性能稍好,但浪费空间

我的磁盘是"动态分配"类型:

  • 虚拟大小 100GB:虚拟机认为自己有 100G 空间(系统内 df -h 显示的也是这个)
  • 实际大小 43.38GB:VDI 文件在物理硬盘上实际占用的空间

为什么会这样?

动态分配磁盘的工作方式:
1. 创建时:只占几 MB
2. 使用时:随着写入数据,文件自动"长大"
3. 上限:不超过设置的"虚拟大小"(100G)

所以我现在的状态是:

维度含义
系统内可用空间99G✅ 可以存 99G 数据
物理硬盘占用43.38G✅ 实际只占 43G 空间
未来增长自动✅ 写入数据时自动膨胀,上限 100G

这意味着:

  • 我现在可以正常使用 100G 空间
  • 但物理硬盘目前只被占用 43G
  • 随着我存入更多数据,VDI 文件会自动增长,最多到 100G

太香了!这才是真正的"按需分配"!


💡 血泪教训总结

1. 扩容前必须先检查快照

血泪教训:

❌ 错误做法:直接扩容 → 系统内不生效
✅ 正确做法:先检查快照 → 清理或克隆 → 再扩容 → 最后扩展分区

检查快照的方法:

<h1>Windows 宿主机</h1>
cd "C:\Program Files\Oracle\VirtualBox"
VBoxManage snapshot "虚拟机名" list

如果有快照,先处理快照再扩容!

2. 快照链复杂时,克隆是最优解

对比各种方案:

方案耗时风险推荐度
删除快照不确定高(可能删不掉)⭐⭐
导出/导入 OVA10-20 分钟⭐⭐⭐
克隆虚拟机5-10 分钟最低⭐⭐⭐⭐⭐
直接删文件1 分钟极高(虚拟机报废)❌ 禁止

克隆命令(建议收藏):

VBoxManage clonevm "原虚拟机名" --name "新虚拟机名" --basefolder "存放路径" --register

3. 扩容后必须在系统内扩展分区

完整流程(缺一不可):

<h1>Step 1: 扩容虚拟硬盘(VirtualBox 层面)</h1>
VBoxManage modifymedium "Ubuntu-Clean-disk1.vdi" --resize 102400



<h1>Step 2: 启动虚拟机,扩展分区表(Ubuntu 层面)</h1>
sudo growpart /dev/sda 2





<h1>Step 3: 扩展文件系统(Ubuntu 层面)</h1>
sudo resize2fs /dev/sda2





<h1>Step 4: 验证</h1>
df -h

缺少任何一步,扩容都不会生效!

4. 动态分配磁盘最省空间

除非你有特殊需求,否则默认使用动态分配:

  • 节省物理硬盘空间
  • 性能差异可以忽略
  • 后期可以转换为固定大小(如果需要)

🔗 完整命令速查(建议收藏)

克隆虚拟机

cd "C:\Program Files\Oracle\VirtualBox"
VBoxManage clonevm "原虚拟机名" --name "新虚拟机名" --basefolder "存放路径" --register

扩容虚拟硬盘

VBoxManage modifymedium "D:\VirtualBox\新虚拟机\新虚拟机-disk1.vdi" --resize 102400
<h1>102400 = 100GB,如需其他容量自行计算(GB × 1024)</h1>

扩展分区(Ubuntu 内)

<h1>查看分区情况</h1>
lsblk



<h1>扩展分区表(假设是 /dev/sda2)</h1>
sudo growpart /dev/sda 2





<h1>扩展文件系统</h1>
sudo resize2fs /dev/sda2





<h1>验证</h1>
df -h

检查快照

VBoxManage snapshot "虚拟机名" list

🎯 写在最后

这篇文章记录了我从崩溃到解决的全过程。

如果你也遇到了同样的问题,希望这篇文章能帮到你。

最重要的是:删快照前一定要三思,克隆是最安全的方案!


📢 下篇预告

下一篇,我会写《【Hermes 系列 7】测试实战:CI-CD 集成-Hermes 接入 Jenkins 全实战》。


如果这篇文章帮到了你,欢迎点赞、转发、关注!

你的支持是我持续创作的动力 💪