Mounting a raw dd image as a VMware virtual disk

Update

If you are having a similar problem you might want to check out raw2vmdk.
It will automate the process for you and have you up and running in a matter of seconds.

———————

This is quite a common and frustrating problem, judging by the amount of Google search results.
And although common, it can be very tricky depending on the circumstances, and if you’re like me and Murphy’s law loves you so much, then you’re in for a very long and exhausting ride.

A Linux OS with VMware Workstation 7 is assumed, however the final approach should theoretically work with previous versions of VMware Workstation and any OS.

There’s actually a number of approaches you can take, each one fulfilling different needs and matching different circumstances.

During my research I found 3:

  • QEMU’s qemu-img tool
    • Pros
      • Easy to use
      • Works well for small images (a couple of GBs)
    • Cons
      • Practically unusable for large images (tens of GBs), conversion will take for ever
  • LiveView
    • Pros
      • Easy to use
      • Takes care of all dependencies, even if you don’t have VMware it’ll set it up for you
      • Doesn’t convert the image, it mounts it straight away, so no waiting
    • Cons
      • MS Windows only
  • Manually editing the .vmdk file to mount the raw image
    • Pros
      • Doesn’t convert the image, it mounts it straight away, so no waiting
      • Simple steps to follow
      • OS independent, you can get the technical details required from any OS
      • No need for additional software
      • You’ll be done in 5 minutes
    • Cons
      • You’ll have to work a bit and edit a file
      • Can’t find any other cons…

So let’s start exploring them.

QEMU’s qemu-img tool

If you have a small enough image, say, a couple of GB, then it’s not much of a problem.
You can just use QEMU’s qemu-img utility to convert the raw image you took using dd to a VMDK virtual disk and just add that to your virtual machine.

qemu-img help output

zapotek@zaptop:~$ qemu-img
qemu-img version 0.12.3, Copyright (c) 2004-2008 Fabrice Bellard
usage: qemu-img command [command options]
QEMU disk image utility

Command syntax:
check [-f fmt] filename
create [-f fmt] [-o options] filename [size]
commit [-f fmt] filename
convert [-c] [-f fmt] [-O output_fmt] [-o options] filename [filename2 [...]] output_filename
info [-f fmt] filename
snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename

Command parameters:
'filename' is a disk image filename
'fmt' is the disk image format. It is guessed automatically in most cases
'size' is the disk image size in bytes. Optional suffixes
'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)
and T (terabyte, 1024G) are supported. 'b' is ignored.
'output_filename' is the destination disk image filename
'output_fmt' is the destination format
'options' is a comma separated list of format specific options in a
name=value format. Use -o ? for an overview of the options supported by the
used format
'-c' indicates that target image must be compressed (qcow format only)
'-h' with or without a command shows this help and lists the supported formats

Parameters to snapshot subcommand:
'snapshot' is the name of the snapshot to create, apply or delete
'-a' applies a snapshot (revert disk to saved state)
'-c' creates a snapshot
'-d' deletes a snapshot
'-l' lists all snapshots in the given image

Supported formats: cow qcow vdi vmdk cloop dmg bochs vpc vvfat qcow2 parallels nbd host_cdrom host_floppy host_device raw tftp ftps ftp https http

qemu-img example

qemu-img convert -f raw diskimage.img -O vmdk vmwaredisk.vmdk

And job done.

But, when you’re dealing with a 70GB raw image don’t even think about it.
You’ll have to wait for hours on end for qemu-img to finish and it’s performance will keep decreasing over time.
And we’re talking about lots of hours here, so that didn’t work for me…

LiveView

The next thing I stumbled upon was LiveView.
It’s written in Java but there’s only support for Windows OS.

It’s a nice tool, it handles its dependencies during the installation process, it’ll even download and set-up VMware Server for you.
But I’m on Linux, so no cigar (so to speak…I must have gone through tens of cigars ’till I found a solution).

From what little I’d gathered, it didn’t sound like it tried to convert the raw image to a vmdk file, like qemu-img, rather than create a vdmk file with the appropriate parameters to make VMware mount the raw image.
So I took a look at LiveView’s code and it turned out I was right.

That was a very good thing, no waiting for a huge raw image to be converted, just modify the vmdk file and we’re all set.
Seemed like there was light at the end of the tunnel after all. :)

And there was no reason why I couldn’t manually replicate LiveView’s process to get the job done, and so I did.

Manually editing the .vmdk file to mount the raw image

Now let’s take a look inside a vmdk file and figure out its structure.
First of all, we need a VMWare virtual disk (vmdk) file.

So just create one with minimum size, let’s say 0.1GB.
Go to your virtual machine’s settings and:
Hardware tab -> Add -> Hard Disk -> Create a new virtual disk -> IDE ->

  1. Set maximum disk size to 0.1GB
  2. Leave the “Allocate all disk space now” checkbox unchecked
  3. Select “Store virtual disk as a single file”

-> Select the name and location of the new disk -> Finish.

Now open the vmdk file with a text editor. It might give a warning that it’s a binary file and you may corrupt it but don’t worry.
The first line in the file is probably the virtual disk header, just remove it and save the file as a simple UTF-8 file, don’t worry about corruption.

So now we have a nice simple plain text vmdk file we can edit to our taste that looks something like this:

version=1
encoding="UTF-8"
CID=fffffffe
parentCID=ffffffff
isNativeSnapshot="no"
createType="monolithicSparse"

# Extent description
RW 208896 SPARSE "FreeBSD 8.0-1.vmdk"

# The Disk Data Base
#DDB

ddb.virtualHWVersion = "7"
ddb.longContentID = "29075898903f9855853610dffffffffe"
ddb.uuid = "60 00 C2 91 8e 73 27 62-43 58 3b f8 05 ae 2e a0"
ddb.geometry.cylinders = "207"
ddb.geometry.heads = "16"
ddb.geometry.sectors = "63"
ddb.adapterType = "ide"

Don’t worry if that looks like gibberish to you, you’re actually one breath away from solving your problem, you can smile and relax. :)
There’s a few thing we need to change, some data under the “Extent description” and “Disk Data Base” sections.
But before we do that, we need some technical details about the drive from which the dd image originated.

We need the following info:

  1. Number of cylinders
  2. Number of heads
  3. Sectors per track
  4. Sector count

You can get your hands on these details in various ways:

1) If you don’t have the drive and don’t know the model you can use WinHex to extract the technical specs we need from the raw image itself, however that didn’t work for me.
Although it’s written for MS Windows it works very well under Wine, but you’re going to need a “Forensic” or “Specialist” license to enable the feature that will gather the required info.

2) If you don’t have the drive but know the drive’s model, just Google it’s technical specs.

3) If you do have the drive getting the info is as easy as:

zapotek@zaptop:~$ sudo hdparm -I /dev/sda
/dev/sda:

[...]
Configuration:
        Logical         max     current
        cylinders       16383   16383
        heads           16      16
        sectors/track   63      63
        --
        CHS current addressable sectors:   16514064
        LBA    user addressable sectors:  234441648
        LBA48  user addressable sectors:  234441648
        Logical/Physical Sector size:           512 bytes
        device size with M = 1024*1024:      114473 MBytes
        device size with M = 1000*1000:      120034 MBytes (120 GB)
        cache/buffer size  = unknown
[...]

Or through a properties menu or something on MS Windows.

The info in bold is what we need.
A generic vmdk template for mounting raw images would look like:

version=1
encoding="UTF-8"
CID=fffffffe
parentCID=ffffffff
isNativeSnapshot="no"
createType="monolithicFlat"

# Extent description
RW [LBA user addressable sectors] FLAT "[RAW image location]" 0

# The Disk Data Base
#DDB

ddb.virtualHWVersion = "7"
ddb.longContentID = "29075898903f9855853610dffffffffe"
ddb.uuid = "60 00 C2 91 8e 73 27 62-43 58 3b f8 05 ae 2e a0"
ddb.geometry.cylinders = "[number of cylinders]"
ddb.geometry.heads = "[number of heads]"
ddb.geometry.sectors = "[number of sectors]"
ddb.adapterType = "ide"

So in our case it becomes:

version=1
encoding="UTF-8"
CID=fffffffe
parentCID=ffffffff
isNativeSnapshot="no"
createType="monolithicFlat"

# Extent description
RW 234441648 FLAT "rawdiskimage.img" 0

# The Disk Data Base
#DDB

ddb.virtualHWVersion = "7"
ddb.longContentID = "29075898903f9855853610dffffffffe"
ddb.uuid = "60 00 C2 91 8e 73 27 62-43 58 3b f8 05 ae 2e a0"
ddb.geometry.cylinders = "16383"
ddb.geometry.heads = "16"
ddb.geometry.sectors = "63"
ddb.adapterType = "ide"

That’s it…we’re done.
Just fire up VMware and mount it, it worked for me, it works for LiveView and it should work for you as well.

C ya and happy mounting!
(No, not in that way…)

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon

Posted in: Temple of Knowledge, Virtualization

Tags: , , , , , , , , ,



addLeave a comment