Monday, April 27, 2009

Mount Xen and VirtualBox Images in Linux

If you use Xen disk images then you can mount them fairly easily to directly modify them on dom0 or another system:

Use "fdisk -luC 530 WinXP.disk" to print the partition table of the disk (where WinXP.disk is your disk image...).
Then multiply sector size by the sector start of the partition you want, then simply mount using that offset:
"sudo mount -o loop,offset=32256 WinXP.disk /media/mountpoint"

For example:
fdisk -luC 530 WinXP.disk

Disk WinXP.disk: 0 MB, 0 bytes
255 heads, 63 sectors/track, 530 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x6c896c89

Device Boot Start End Blocks Id System
WinXP.disk1 * 63 41913584 20956761 7 HPFS/NTFS
Partition 1 has different physical/logical endings:
phys=(1023, 254, 63) logical=(2608, 254, 63)

Then 63 sectors * 512 bytes per sector =32256, so:
sudo mount -o loop,offset=32256 WinXP.disk /media/mountpoint

This info was found here.

In VirtualBox the operation is similar, but since the .vdi format is different you have to jump through another hoop. Note this only works with fixed size images. First you have to find the start of the disk, then use that to find the start of the partition:

od -j344 -N4 -td4 image.vdi | awk 'NR==1{print $2;}'

Now use the number it returns as #offset# in:
dd if=image.vdi of=vdstart bs=1 skip=#offset# count=1b
/sbin/sfdisk -luS vdstart

This takes the partition table of the virtual disk, dumps it to a file, then reads the partition table to tell you where the partition starts. Now the process is similar to Xen, multiply the sector size by the sector offset of the partition to find the start of the partition, but you also have to add the vdi offset you found before. You can then use that offset to mount the partition:
mount -o loop,offset=39424,ro image.vdi /media/image/

For Example:

$ od -j344 -N4 -td4 DOS.vdi | awk 'NR==1{print $2;}'
$ dd if=DOS.vdi of=vdstart bs=1 skip=7168 count=1b
512+0 records in
512+0 records out
512 bytes (512 B) copied, 0.00523881 s, 97.7 kB/s
$sfdisk -luS vdstart
Disk vdstart: cannot get geometry

Disk vdstart: 0 cylinders, 255 heads, 63 sectors/track
Warning: The partition table looks like it was made
for C/H/S=*/64/63 (instead of 0/255/63).
For this listing I'll assume that geometry.
Units = sectors of 512 bytes, counting from 0

Device Boot Start End #sectors Id System
vdstart1 * 63 3253823 3253761 6 FAT16
vdstart2 0 - 0 0 Empty
vdstart3 0 - 0 0 Empty
vdstart4 0 - 0 0 Empty
$sudo mount -o loop,offset=39424,ro DOS.vdi /media/dos/

The mount offset was calculated by: 7168 (vdi header) + 63 (sectors) * 512 (bytes per sector) = 39424

Works like a charm :) Thanks Przemoc. More info can be found here.

I am still looking for a way to do it with Snapshots though :/. On a different note, this looks like it could be useful.

No comments: