![将所有文件移回虚拟机驱动器后无法正常启动](https://linux22.com/image/50854/%E5%B0%86%E6%89%80%E6%9C%89%E6%96%87%E4%BB%B6%E7%A7%BB%E5%9B%9E%E8%99%9A%E6%8B%9F%E6%9C%BA%E9%A9%B1%E5%8A%A8%E5%99%A8%E5%90%8E%E6%97%A0%E6%B3%95%E6%AD%A3%E5%B8%B8%E5%90%AF%E5%8A%A8.png)
我在 VirtualBox 中使用 .vdi 磁盘创建了一个 Ubuntu 12.04 32 位虚拟机。然后,我使用 qemu-nbd 挂载该磁盘并将所有文件移出该磁盘;然后回到它。当我再次启动虚拟机时,我得到不同的结果:
- Ubuntu 告诉我出现错误并询问我是否要修复/跳过/忽略/手动修复。如果我修复了,它将重新启动并启动到 tty。如果我忽略它,它将启动到 tty。我还没有尝试过跳过/手动修复。
- 启动到空白的紫色屏幕。冻结。在随后的重置中,启动到闪烁的文本光标。
- 启动至 Ubuntu 初始屏幕,冻结。重置后,请参阅此列表中的第 1 项。
我的问题是: 为什么会出现这种情况? Grub 中是否有一些磁盘硬件地址引用 /boot/?有没有办法删除和替换 VHD 中的文件而不会出现此问题?
如何重现这个结果(我希望):
- 使用 8GB .vdi 虚拟磁盘在 VirtualBox 中创建虚拟机(称为 ub.vdi,用于问题的其余部分)
- 使用 Ubuntu 12.04.3 32 位安装 ISO 启动
- “尝试Ubuntu”。
- 设置一个MSDOS分区表和两个主分区,一个2048MiB交换空间,其余一个ext4分区。 (使用 gparted)。
- 在ext4分区上安装Ubuntu
- 关闭虚拟机
- 导航到您的 VM 目录并运行以下脚本:
#!bin/bash
# load the nbd module
sudo modprobe nbd
# make a folder for our virtual disk files
mkdir os_files
# load the virtual disk as a device (nbd0)
sudo qemu-nbd -c /dev/nbd0 ub.vdi
sleep 1
# create a directory and mount the os partition to it
MNT_DIR=$(mktemp -d)
sudo mount /dev/nbd0p2 $MNT_DIR
# move the os files off, then back onto the virtual disk
find $MNT_DIR -maxdepth 1 -mindepth 1 | xargs -I{} sudo mv {} os_files/
find os_files/ -maxdepth 1 -mindepth 1 | xargs -I{} sudo mv {} $MNT_DIR
# clean up
sudo umount $MNT_DIR
sudo qemu-nbd -d /dev/nbd0
rm os_files/ $MNT_DIR -r
unset MNT_DIR
你为什么做这个?
作为合同要求的一部分,我需要将虚拟磁盘存储在版本控制中。在版本控制中拥有巨大的二进制 blob(虚拟磁盘)是一件痛苦的事情,主要是对于克隆(git)/签出(svn)来说,但对于差异来说也是如此。我考虑过拆分为多个文件,但我需要能够操作上面 (5) 中提取的操作系统/数据。请注意,我的 VCS 存储库仍然需要构建完整 VM 所需的所有信息。
也可以看看:https://superuser.com/questions/641971/manual-clone-recreate-virtual-disk。如果再次发帖显得不礼貌/忘恩负义/不惯用/粗鲁等等,我深表歉意;我在 SU 收到的答案虽然有用,但缺乏实际解决我的问题的专业知识。请注意,我在这里提出的问题比链接的问题更具体一些,但任何完全规避该问题的想法都非常受欢迎。
答案1
引导加载程序需要在特定位置找到某个文件。 Ubuntu 使用 Grub 作为其默认引导加载程序,Grub 包含一个用于加载 Linux 内核的文件系统驱动程序,但 Grub 需要找到其文件系统驱动程序。此外,
如果您尝试通过创建空白磁盘并对其进行分区来从头开始重新创建虚拟机,情况会更糟:该磁盘将不包含引导加载程序。
作为额外的恢复步骤,您需要重新安装引导加载程序。我认为下面的命令应该可以做到这一点(您可能需要一些其他选项来确保 Grub 包含必要的设备驱动程序):
/usr/sbin/grub-install --root-directory="$MNT_DIR" /dev/nbd
并确保/boot/grub/device.map
包含
(hd0) /dev/nbd
请注意,如果您在虚拟机中运行,这device.map
将不起作用。grub-install
如果这很重要,请device.map
围绕调用进行保存和恢复,或者手动调用最终运行的grub-install
低级命令。grub-install
另一种方法是使用仅包含引导加载程序的小型启动磁盘来设置虚拟机,您不会介意一直从头开始构建(或者您可以在引导加载程序每次更改时缓存构建的副本,这应该发生)很少)。