First I created a virtual disk and configured the file size to be fixed. I doubt there are any simple ways of doing what I plan to with a dynamic file. Using the VM I formated the drive with one full size FAT32 partition. I also added some dummy files just for testing purposes. The rest is done in the host OS.
Before messing with the .vdi file in any way, make sure the guest OS is shutdown. Not suspended or saved state.
I then opened the vdi file in a gui hex editor that came with my distribution called KHexEdit. My virtual disk was only 300 MB and I have 1GB of ram. Using KHexEdit with multi GB files may not work so well. An alternative may be using the console command hexdump with appropriate options and piping output into more. Or you could dd the first 1 MB of your vdi file to another file and just open that. It helps to get an ascii view. The vdi file starts with “0000000000 <<< InnoTek VirtualBox Disk Image >>>...........................”
I then located the start of the FAT32 partition. Being the only partition on the drive, it's beginning was near the start of the file.
- Code: Select all Expand viewCollapse view
0000034176 ................................................................
0000034240 ................................................................
0000034304 ëX.MSDOS5.0..."......ø..?.ÿ.?...gP..S...........................
0000034368 ..)2úÏøNO NAME FAT32 3É.Ѽô{.Á.Ù½.|.N..V@´.Í.s.¹ÿÿ.ñf.¶Æ@f.
0000034432 ¶Ñ.â?÷â.ÍÀí.Af.·Éf÷áf.Fø.~..u8.~*.w2f.F.f.À.»..¹..è+.éH. ú}´}.ð¬
0000034496 .Àt.<ÿt.´.»..Í.ëî û}ëå ù}ëà.Í.Í.f`f;Fø..J.fj.fP.Sfh.....~.... .´
0000034560 A»ªU.V@Í......ûUª....öÁ.....þF.´B.V@.ôÍ.°ùfXfXfXfXë*f3Òf.·N.f÷ñþ
0000034624 Â.Êf.ÐfÁê.÷v..Ö.V@.èÀä..̸..Í.fa..Tÿ.Ã..f@I..qÿÃNTLDR .....
0000034688 ..............................................Remove disks or ot
0000034752 her media.ÿ..Disk errorÿ..Press any key to restart.......¬ËØ..Uª
0000034816 RRaA............................................................
0000034880 ................................................................
0000034944 ................................................................
The start is somewhat obvious; or at least it is to me. The “MSDOS” is a big hint. If you are having trouble finding it, here is a tip. Label the partition with a unique name. The volume's name is stored near the very beginning of the filesystem so by searching for its first occurrence, you will find yourself within a few lines of the beginning. I don't recall labeling this volume anything which would explain the “NO NAME”. There also seems to be a lot of blank spaces in the beginning of the file which aids greatly when searching by eye. By the looks of this output, I would say the FAT32 partition starts with an offset of 34304. Note: that is in decimal, not hexadecimal. By default KHexEdit displays addresses in hex, and so I had to change that. I have done this process twice now and the addresses where not the same so I doubt my number will work for you. Both where in the 30000's though. Now we have the information we need.
To mount, I first created a directory /mnt/vdifs. All that's left is the mount command. After much trial and error I finally had success with:
- Code: Select all Expand viewCollapse view
sudo mount -o loop,offset=34304,umask=000 /foo/bar.vdi /mnt/vdifs
Because only root has mounting privileges on my system I used sudo. For those familiar with mount it should be obvious that /foo/bar.vdi is the image I want to mount and /mnt/vdifs is where I want to mount it. The magic is in the options. -o is used to signify the start of mounting options. “loop” specifies that the source is a file already mounted within the system. Loop can be used like “loop=/dev/loop1” which would specify which loop device to use, but when entered alone mount decides which one to use. “offset=34304” is where within the file the filesystem starts. I am uncertain whether or not most filesystems specify their length or if it is determined by the partition table alone. If it is specified only by the partition table then there could be trouble if the partition doesn't extend to the very last byte of the drive. Mount may assume the filesystem's length is to the end of the vdi file and if this is not true data may be written out of the partition's boundaries. Even if the partition extends to the last byte of the virtual drive, it may not end on the last byte of the vdi file. I haven't examined the vdi file structure but I have been assuming that all VirtualBox related data is written at the start, leaving only raw hard drive data to be written to the end. This of cause only works with fixed size images because dynamic files will probably not be written in a linear fashion. Despite all the possible hang ups, I have not yet had a problem. One last option deals with file permissions. Because dos filesystems don't implement permissions like Linux filesystems do, the filesystem will be mounted as belonging to root. If regularly users need to be able to write to the drive, adding umask=000 will set all files writable by all users. One more point worth mentioning, if the offset was set correctly, mount should be able to determine the filesystem type by itself. If the offset was incorrect, mount will fail and you will probably receive an error message saying you need to indicate the filesystem type because mount doesn't know what the heck it's looking at. Don't be mistaken and assume that all you need to do is add a -t option.
After all this effort what has been accomplished? Using my custom mount command, I can now mount my vdi file into my Linux filesystem with full read and write capabilities and all operations are performed at full speed. I can even run fsck on the loop device if I know which one was used. Perhaps even use dd to copy a real partition into my vdi image file. Some cautions need to be taken though. Obviously, you should always make backups if the data is important. Also, be sure to unmount before starting your VM and never mount unless the VM has been shutdown or at least unmounted the partition. Just for fun I tried writing to the vdi file while the VM was using it and just like expected, I broke the filesystem. Data was written by the host, but the guest overwrote some the the TOC creating a mess. The files were not visible but the space they occupied was marked used, so the space was unrecoverable without a scandisk or fsck.
Maybe you learned something, maybe you didn't. If this helps you in some way then great, otherwise hopefully you at least enjoyed the read. If nothing else, this does prove plausibility of mounting vdi images in a useful way. With any luck, future versions of VirtualBox will incorporate this feature with only point and click needed to use. Doing this through VirtualBox could also ensure that vdi files are not mounted on the host and guest at the same time.