如何将平面原始磁盘映像转换为 vmdk?

我有一些旧 Linux 文件系统的平面文件格式的旧图像。它们可以被 Bochs使用,但是我需要用 虚拟盒子运行它们。Virtual Box 不能使用这种格式的图像,所以我需要将这些图像从平面文件转换为。文件格式。有什么办法吗?

214763 次浏览

首先,安装 QEMU。在像 Ubuntu 这样基于 Debian 的发行版上,运行:

$ apt-get install qemu

然后运行以下命令:

$ qemu-img convert -O vmdk imagefile.dd vmdkname.vmdk

我假设平面磁盘映像是 dd风格的映像。转换操作还处理许多其他格式。

有关 qemu-img命令的更多信息,请参见

$ qemu-img -h

也许你应该尝试使用星风 V2V 转换器,你可以从这里得到它-http://www.starwindsoftware.com/converter。它还支持 IMG 磁盘格式,并执行 IMG、 VMDK 或 VHD 之间的扇区与扇区之间的转换,无需对源图像做任何更改。这个工具是免费的:)

在窗口上,使用 https://github.com/Zapotek/raw2vmdk将 dd 或 winhex 创建的原始文件转换为 vmdk。Raw2vmdk v0.1.3.2有一个 bug ——一旦创建了 vmdk 文件,编辑 vmdk 文件并修复原始文件的路径(在我的例子中是 D: Temp flash _ 16gb)。Raw (由 winhex 创建)生成的路径是 D: Tempflash _ 16gb。生)。然后,在 vmware 虚拟机版本6.5-7中打开它(5.1拒绝附加 vmdk 硬盘)。啊!

因为问题提到了 VirtualBox,所以这个目前可以工作:

VBoxManage convertfromraw imagefile.dd vmdkname.vmdk --format VMDK

不带参数地运行它,获得一些有趣的细节(特别是 --variant标志) :

VBoxManage convertfromraw

克罗森沃德的回答启发了下面的脚本,它做了以下事情:

  • 通过 ssh 从远程服务器获取 dd 转储(作为 gz 文件)
  • 拉开垃圾场的拉链
  • 转换成 vmware

脚本是可重新启动的,并检查中间文件的存在。它还使用 pv 和 qemu-img-p 来显示每个步骤的进度。

在我的环境2 x Ubuntu 12.04 LTS 中采取了以下步骤:

  • 获得一个60GByte 分区的47GByte 磁盘转储需要3个小时
  • 20分钟解压缩到60GByte dd 文件
  • 创建 vmware 文件需要45分钟
#!/bin/bash
# get a dd disk dump and convert it to vmware
#  see http://stackoverflow.com/questions/454899/how-to-convert-flat-raw-disk-image-to-vmdk-for-virtualbox-or-vmplayer
#  Author: wf  2014-10-1919


#
# get a dd dump from the given host's given disk and create a compressed
#   image at the given target
#
#  1: host e.g. somehost.somedomain
#  2: disk e.g. sda
#  3: target e.g. image.gz
#
# http://unix.stackexchange.com/questions/132797/how-to-use-ssh-to-make-a-dd-copy-of-disk-a-from-host-b-and-save-on-disk-b
getdump() {
local l_host="$1"
local l_disk="$2"
local l_target="$3"
echo "getting disk dump of $l_disk from $l_host"
ssh $l_host sudo fdisk -l  | egrep "^/dev/$l_disk"
if [ $? -ne 0 ]
then
echo "device $l_disk does not exist on host $l_host" 1>&2
exit 1
else
if [ ! -f $l_target ]
then
ssh $l_host "sudo dd if=/dev/$disk bs=1M | gzip -1 -" | pv | dd of=$l_target
else
echo "$l_target already exists"
fi
fi
}


#
# optionally install command from package if it is not available yet
# 1: command
# 2: package
#
opt_install() {
l_command="$1"
l_package="$2"
echo "checking that $l_command from package $l_package  is installed ..."
which $l_command
if [ $? -ne 0 ]
then
echo "installing $l_package to make $l_command available ..."
sudo apt-get install $l_package
fi
}


#
# convert the given image to vmware
#  1: the dd dump image
#  2: the vmware image file to convert to
#
vmware_convert() {
local l_ddimage="$1"
local l_vmwareimage="$2"
echo "converting dd image $l_image to vmware $l_vmwareimage"
#  convert to VMware disk format showing progess
# see http://manpages.ubuntu.com/manpages/precise/man1/qemu-img.1.html
qemu-img convert -p -O vmdk "$l_ddimage" "$l_vmwareimage"
}


#
# show usage
#
usage() {
echo "usage: $0 host device"
echo "      host: the host to get the disk dump from e.g. frodo.lotr.org"
echo "            you need ssh and sudo privileges on that host"
echo "
echo "    device: the disk to dump from e.g. sda"
echo ""
echo "  examples:
echo "       $0 frodo.lotr.org sda"
echo "       $0 gandalf.lotr.org sdb"
echo ""
echo "  the needed packages pv and qemu-utils will be installed if not available"
echo "  you need local sudo rights for this to work"
exit 1
}


# check arguments
if [ $# -lt 2 ]
then
usage
fi


# get the command line parameters
host="$1"
disk="$2"


# calculate the names of the image files
ts=`date "+%Y-%m-%d"`
# prefix of all images
#   .gz the zipped dd
#   .dd the disk dump file
#   .vmware - the vmware disk file
image="${host}_${disk}_image_$ts"


echo "$0 $host/$disk ->  $image"


# first check/install necessary packages
opt_install qemu-img qemu-utils
opt_install pv pv


# check if dd files was already loaded
#  we don't want to start this tedious process twice if avoidable
if [ ! -f $image.gz ]
then
getdump $host $disk $image.gz
else
echo "$image.gz already downloaded"
fi


# check if the dd file was already uncompressed
# we don't want to start this tedious process twice if avoidable
if [ ! -f $image.dd ]
then
echo "uncompressing $image.gz"
zcat $image.gz | pv -cN zcat > $image.dd
else
echo "image $image.dd already uncompressed"
fi
# check if the vmdk file was already converted
# we don't want to start this tedious process twice if avoidable
if [ ! -f $image.vmdk ]
then
vmware_convert $image.dd $image.vmdk
else
echo "vmware image $image.vmdk already converted"
fi

为了回答 TJJ: 但是不复制整个文件也可以做到这一点吗?,我们需要创建一个额外的 vmdk-meta 文件,它引用原始 dd-image。

是的 ,这是可能的。下面是如何在 VirtualBox 中使用平面磁盘映像:

首先,按照通常的方法用 dd 创建一个图像:

dd bs=512 count=60000 if=/dev/zero of=usbdrv.img

然后您可以为 VirtualBox 创建一个引用此图像的文件:

VBoxManage internalcommands createrawvmdk -filename "usbdrv.vmdk" -rawdisk "usbdrv.img"

您可以按原样在 VirtualBox 中使用这个映像,但是根据客户操作系统的不同,这个映像可能不会立即显示出来。例如,我在一个 Windows 客户操作系统上尝试使用这种方法,我必须做以下事情才能给它一个驱动器号:

  • 去控制面板。
  • 转到管理工具。
  • 进入电脑管理系统。
  • 转到左侧面板中的存储磁盘管理。
  • 你可以在这里看到你的光盘。在它上面创建一个分区并格式化它。对小卷使用 FAT,对大卷使用 FAT32或 NTFS。

您可能需要访问 Linux 上的文件。首先从客户操作系统卸载它,以确保将其从虚拟机中删除。现在我们需要创建一个引用该分区的虚拟设备。

sfdisk -d usbdrv.img

回应:

label: dos
label-id: 0xd367a714
device: usbdrv.img
unit: sectors


usbdrv.img1 : start=          63, size=       48132, type=4

注意分区的起始位置: 63。在下面的命令中,我使用了 loop 4,因为在我的例子中,它是第一个可用的 loop 设备。

sudo losetup -o $((63*512)) loop4 usbdrv.img
mkdir usbdrv
sudo mount /dev/loop4 usbdrv
ls usbdrv -l

回应:

total 0
-rwxr-xr-x. 1 root root 0 Apr  5 17:13 'Test file.txt'

耶!

为了给您提供另一种选择,您也可以使用 https://sourceforge.net/projects/dd2vmdk/。Dd2vmdk 是一个基于 * nix 的程序,它允许你挂载原始磁盘映像(由 dd、 dcfldd、 dc3dd、 ftk image 等创建) ,方法是获取原始映像,分析主引导记录(物理扇区0) ,并获取创建 vmdk 文件所需的特定信息。

就个人而言,imo Qemu 和 Zapotek 的 raw2vmdk 工具是将 dd 转换为 vmdks 的最佳总体选项。

披露: 我是这个项目的作者。