Tag Archives: vmdk

Read and writing VMware .vmdk disks

(This is in answer to an IRC question, but the answer is a bit longer than I can cover in IRC)

Can you read and write at the block level in a .vmdk file? I think the questioner was asking about writing a backup/restore type tool. Using only free software, qemu can do reads. You can attach qemu-nbd to a vmdk file and that will expose the logical blocks as NBD, and you can then read at the block level using libnbd:

#!/usr/bin/python3
import nbd
h = nbd.NBD()
h.connect_systemd_socket_activation(
    ["qemu-nbd", "-t", "/var/tmp/disk.vmdk"])
print("size = %d" % h.get_size())
buf = h.pread(512, 0)
$ ./qemu-test.py 
size = 1073741824

The example is in Python, but libnbd would let you do this from C or other languages just as easily.

While this works fine for reading, I wouldn’t necessarily be sure that writing is safe. The vmdk format is complex, baroque and only lightly documented, and the only implementation I’d trust is the one from VMware.

So as long as you’re prepared to use a bit of closed source software and agree with the (nasty) license, VDDK is the safer choice. You can isolate your own software from VDDK using our nbdkit plugin.

#!/usr/bin/python3
import nbd
h = nbd.NBD()
h.connect_command(
    ["nbdkit", "-s", "--exit-with-parent",
     "vddk", "libdir=/var/tmp/vmware-vix-disklib-distrib",
     "file=/var/tmp/disk.vmdk"])
print("size = %d" % h.get_size())
buf = h.pread(512, 0)
h.pwrite(buf, 512)

I quite like how we’re using small tools and assembling them together into a pipeline in just a few lines of code:

┌─────────┬────────┐          ┌─────────┬────────┐
│ your    │ libnbd │   NBD    │ nbdkit  │ VDDK   │
│ program │     ●──────────────➤        │        │
└─────────┴────────┘          └─────────┴────────┘
                                          disk.vmdk

One advantage of this approach is that it exposes the extents in the disk which you can iterate over using libnbd APIs. For a backup tool this would let you save the disk efficiently, or do change-block tracking.

1 Comment

Filed under Uncategorized

Examine VMWare ESX with libguestfs

We worked out yesterday (thanks Matthias Bolte) how to use the libguestfs tools like virt-inspector and guestfish to examine VMWare VMs.

VMWare’s native disk format is VMDK, which is only partially understood by free tools like qemu-img. qemu-img breaks quite badly on the newer variant that ESX 4 uses. Then there’s the issue of how you get the VMDK file from VMWare’s storage. Use their proprietary storage APIs?

Well it turned out both problems could be solved easily. VMWare ESX servers make the storage available over https connections, so you can use a URL like https://root:password@esxserver/folder/ to browse available storage on the server. And VMWare also makes the raw (“flat”) disk images available in the same way.

libvirt has supported ESX management for a while (thanks again to Matthias Bolte), so you can do:

$ sudo virsh -c esx://192.168.2.121/?no_verify=1 list --all
Enter username for 192.168.2.121 [root]:
Enter root password for 192.168.2.121:
 Id Name                 State
----------------------------------
  - TestLinux            shut off
  - TestWin              shut off

(Note that the domains must be shut off before VMWare will allow you to access the flat disk images).

Then we can get the storage URL:

$ sudo virsh -c esx://192.168.2.121/?no_verify=1 dumpxml TestLinux > /tmp/xml
$ grep '<source file' /tmp/xml
      <source file='[Storage1] TestLinux/TestLinux.vmdk'/>

And from that storage URL you can grab the disk image directly:

$ wget --no-check-certificate 'https://root:password@192.168.2.121/folder/TestLinux/TestLinux-flat.vmdk?dcPath=ha-datacenter&dsName=Storage1'

The large flat file downloaded is a straight raw disk image that can be examined directly in programs like guestfish and virt-inspector:

$ virt-list-filesystems -al TestLinux-flat.vmdk
/dev/sda1 ext4
/dev/vg_testlinux/lv_root ext4
/dev/vg_testlinux/lv_swap swap

$ guestfish --ro -a TestLinux-flat.vmdk -m /dev/vg_testlinux/lv_root

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for help with commands
      'quit' to quit the shell

><fs> ll /
total 116
dr-xr-xr-x.  23 root root  4096 Dec 30 06:27 .
dr-xr-xr-x   29 root root     0 Dec 21 07:59 ..
-rw-r--r--.   1 root root     0 Dec 30 06:27 .autofsck
drwx------.   3 root root  4096 Dec 17 11:58 .dbus
-rw-r--r--.   1 root root     0 Dec 17 12:50 .readahead_collect
dr-xr-xr-x.   2 root root  4096 Dec 17 12:11 bin
[etc]

It’s probably also possible to avoid the download step, since libguestfs is built on qemu which should support http(s) connections directly, but I didn’t try this yet.

3 Comments

Filed under Uncategorized