Convet VMDK Disk Image to RAW

Last modified on 2009-12-01

As there are already so many pre-built VMware images, we don't need rebuild them for other VMMs (Virtual Machine Monitor) such as Xen, QEMU, etc. We can just convert the disk from vmdk to raw.

There are several ways to get it done. The following tutorial use an VMware guest OS which has 40G disk image and the image is divided into 2G files:

# ls /RHEL4U4/
nvram              RHEL4U4-s007.vmdk  RHEL4U4-s014.vmdk  RHEL4U4-s021.vmdk
RHEL4U4-s001.vmdk  RHEL4U4-s008.vmdk  RHEL4U4-s015.vmdk  RHEL4U4.vmdk
RHEL4U4-s002.vmdk  RHEL4U4-s009.vmdk  RHEL4U4-s016.vmdk  RHEL4U4.vmdk.WRITELOCK
RHEL4U4-s003.vmdk  RHEL4U4-s010.vmdk  RHEL4U4-s017.vmdk  RHEL4U4.vmsd
RHEL4U4-s004.vmdk  RHEL4U4-s011.vmdk  RHEL4U4-s018.vmdk  RHEL4U4.vmx
RHEL4U4-s005.vmdk  RHEL4U4-s012.vmdk  RHEL4U4-s019.vmdk  vmware.log
RHEL4U4-s006.vmdk  RHEL4U4-s013.vmdk  RHEL4U4-s020.vmdk

Using qemu-img

Convert VMDK to RAW using qemu-img is a unofficial method, but has been proven reliable and efficient. You should download and install QEMU first. The following script "vmdk2raw.sh" can do this job:

#!/bin/sh

for i in `ls *[0-9].vmdk`; do
    qemu-img convert -f vmdk $i -O raw ${i/vmdk/raw}
done

cat *.raw >> system.img

Using Xen Blktap driver

We can also make use of the xen blktap driver. Attach the disk image to a running domain (dom0 also works) and dd it out:

#!/bin/sh

xm block-attach 0 tap:vmdk:/RHEL4U4/RHEL4U4.vmdk xvdb w 0
dd if/dev/xvdb of=system.img

Using VMware tools to mount the VMDK image and copy the contents to a RAW disk.

First we should mount the filesystem within the disk.

Use vmware-mount.pl:

# make mount point
# mkdir -p /tmp/vmdk_mount_point

## print the partition table
# vmware-mount.pl -p /RHEL4U4/RHEL4U4.vmdk
Nr      Start       Size Type Id Sytem
-- ---------- ---------- ---- -- ------------------------
 1         63   82815012 BIOS 83 Linux
 2   82815075    1044225 BIOS 82 Linux swap

## mount the first partition
# vmware-mount.pl /RHEL4U4/RHEL4U4.vmdk 1 /tmp/vmdk_mount_point/

In fact, vmware-mount.pl is a wrapper of vmware-loop. When vmware-mount.pl don't work properly, you can use vmware-loop directly:

## make Network Block Device (NBD) file node
# mknod /tmp/vmdk.nbd b 43 0

## print the partition table
# vmware-loop -p /RHEL4U4/RHEL4U4.vmdk
Nr      Start       Size Type Id Sytem
-- ---------- ---------- ---- -- ------------------------
 1         63   82815012 BIOS 83 Linux
 2   82815075    1044225 BIOS 82 Linux swap

## mount the first partition
# vmware-loop /RHEL4U4/RHEL4U4.vmdk 1 /tmp/vmdk.nbd

## open another terminal and mount the device
# mount /tmp/vmdk.nbd /tmp/vmdk_mount_point

Then you can make a 40G raw disk image and copy the contents using the following scripts:

#!/bin/sh

# Create 40G sparse file
dd if=/dev/zero of=/tmp/disk.img bs=1M seek=40960 count=0

# Loop back it
losetup /dev/loop0 system.img

# Do partitioning, using here documents. Change it to fit your schema.
fdisk /dev/loop0 <<EOF
n
p
1


w
EOF

# Create device maps for the partitions
kpartx -a /dev/loop0

# Make filesystem
mkfs.ext3 /dev/mapper/loop0p1

# Make mount point
mkdir -p /tmp/raw_mount_point

# Do mount
mount /dev/mapper/loop0p1 /tmp/raw_mount_point

# Copy contents
cd /tmp/vmdk_mount_point; find . | cpio -pdumv /tmp/raw_mount_point

Reference

  1. VMware Virtual Machine Disk Format (VMDK).
  2. QEMU open source processor emulator.