Tuesday, August 6, 2013

How to mount a VirtualBox .VDI images on a Mac OS X host

Sometimes it is very useful to mount VirtualBox .VDI images on the host system. This allows us to browse file like other file on the system. I am describing the method I used to mount the VDI images in the Mac OS system. Mounting the VDI image in Linux system is similar and in fact much easier with the availability of some other tool.For mounting the VirtualBox .VDI file, I google a bit and found the way to do it.

Here is a Geeky way of Mounting VirtuaBox .VDI image to Unix like operating system like Mac OS. In Mac OS, we can use hdid tool and in Linux/Solaris, we can use losetup resp. lofiadm to do this. I carried out following steps for mounting .VDI to Mac OS. I have explained it with the places where I made mistakes and what I did to correct those mistakes.

First: I searched and found the VirtualBox.VDI image file, that I wanted to mount
  1. Close the virtual box. It cannot be done when VrrtualBox is running
  2. Find the folder where the image is stored. This is generally stored under BirtualBox folder. We can find .VDI files if unable to find the folder. The image file I found was named ubuntu.vdi
  3. I changed it to current directory in the terminal by using cd command
    $ cd /Users/Username/VirtualBox/ubuntu
    $ ls -l
    total 13123696
    drwx------ 6 Username staff        204 Aug 5 01:12 Logs
    -rw------- 1 Username staff       7969 Aug 5 11:03 ubuntu.vbox
    -rw------- 1 Username staff       7968 Aug 5 11:03 ubuntu.vbox-prev
    -rw------- 2 Username staff 3359657984 Aug 5 15:41 ubuntu.vdi
Second: I tried to mount the file with hdid utility
  1. I tried to use hdid utility to mount .VDI image file. The -nomount switch does not mount the image automatically, but makes it available under /dev folder
    $ hdid -nomount ubuntu.vdi
  2. But this returned an error. The .VDI format was not recognized by hdid utility
    $ hdid: attach failed - not recognized
  3. I tried to supply different extension (.IMG) to the hdid utility, by linking ubuntu.vdi to ubuntu.img 
    $ ln ubuntu.vdi ubuntu.img
  4. Now I tried to mount it again with different extension
    $ hdid -nomount ubuntu.img
    /dev/disk1
  5. Now, hdid recognized the image and it was available in /dev/disk2 but it could not be read properly due to unrecognized format in the file. The unrecognized format was due to the header information in the .VDI file 
Additional information about VDI image
hdid utility actually attaches raw disk image via a blockdevice. But .VDI image contains header information with partition information and raw disk image after that. hdid expects only raw disk image. So I had to find where the VirtualBox .VDI header stops and the raw disk image begins.

To find the starting position of raw disk image, we have to do some simple calculations with these facts in consideration
  1. It is decided by reading 4-byte, 32-bit integer at byte offset 0x158 (decimal 344) in the .VDI file.
  2. This value is divided by number of bytes per sector that is 0x200 (decimal 512)
  3. The final value can be used with --section parameter in hdid utility to mount the image.
  4. The mounted image can be used from cli or gui alike
Third: I found the position from which the raw disk image starts
  1. We can use the hexdump utility icluded with Mac OS to retrieve the value where the raw disk image begins. I used man hexdump to read more about it.
    $ hexdump -C -s 0x158 -n 4 ubuntu.vdi
  2. Here, the switches -C is canonical display, -s is skip offset byte from beginning, and -n is length bytes of input. Since I had to read 4-byte, I used -n 4; at the byte offset 0x158, I used -s 0x158. I got following result:
    00000158  00 50 00 00             |.P..|
    0000015c
  3. I got the byte position I need. it is 0x00005000. The color is used here to show the position of the number. It is read two digits at a time back to the front. The byte position I need is  0x5000 (omitting leading zeros). 
  4. But I need number of sectors, so I had to divide the number by 0x200 (decimal 512) to get the appropriate disk position. I used bc command to calculate this. You can optionally use calculator to get the number of sectors.
    I need the result of 5000 / 200 (in hex)
    $ echo "obase=16; ibase=16; 5000 / 200" | bc
    28
  5. The number of sectors to offset is 28. Now I can use hdid utility to safely mount this image.
Four: I Attached the image with hdid utility with -section switch, to offset 28 sectors
  1. Now I again used hdid utility to mount the image by offsetting 28 sectors.
    $ hdid -section 0x28 ubuntu.img
  2. This again returned an error
    hdiutil: attach failed - Resource temporarily unavailable
  3. This was because, i previously attached the ubuntu.img without supplying the -section switch. The image was currently mounted, but unrecognized by Mac OS.
  4. I unmounted the image and mounted it again with -section switch. 
    hdiutil detach /dev/disk1
  5. Mount this image again
    hdid -section 0x28 ubuntu.img
  6. This again returned an error
    vhdiutil: attach failed - no mountable file systems
  7. The automount failed so run hdid with -nomount switch
    hdid -section 0x28 -nomount ubuntu.img
    /dev/disk1
Mac OS primarily support HFS. In addition, it has extended support for FAT32, UDF, UFS, and NTFS (in read only mode). However, it has no support for ext2/ext3 filesystem popular in Linux. We need to do one further step to mount ext2/ext3 file systems.

Five: I installed driver softwares that made me able to mount ext2/3 filesystem and mount it again
  1. Install the latest release of MacFUSE from google: http://code.google.com/p/macfuse/ . This software is not currently being developed.
  2. This piece of software however does not support ext file systems. You have to download a separate module for that Install the ext2 FUSE module: http://sourceforge.net/projects/fuse-ext2/
  3. Now you can use the disk utility or following command to mount the image.
    fuse-ext2 /dev/disk1s1 /Volumes/tmpfolder
  4. We can use -o force command to make the disk writeable.
    fuse-ext2 -o force /dev/disk1s1 /Volumes/tmpfolder

Sunday, August 4, 2013

How I shared MAC OS X folder to Ubuntu Guest OS in Virtual Box

Here is How I installed VirtualBox CD in Ubuntu Server from command line.

I have presented here the steps through which I was able to 
Step 0: Download and install Virtual Box Guest Additions for enabling shared folder and some other tasks.

Step 1: Create new CD/DVD controller if not present. This option is generally not needed if you have not changed anything after install. You can skip to step 2.
  1. Click the Virtualbox session and click settings
  2. Click Storage
  3. Click Controller: Ide Controller under Storage Tree
  4. There are small icons of cd and Hard disk with plus (+) sign
  5. Click on the + sign with cd to add CD/DVD image
  6. On the prompt, click Leave Empty. You can optionally mount VirtualBoxGuestAdditions.iso image on the prompt. But for now you can safely click leave empty
  7. Now click ok and close
Step 2: Install Guest Additions
  1. Start the VirtualBox Session with Ubuntu Server
  2. On the top menu, click Devices > Install Guest Additions. This will add the VirtualBoxGuestAdditions.iso cd to the cd drive.
  3. Find this cd image in the guest Ubuntu server OS. It might be present in
    /dev/cdrom or /dev/disk/by-label/VBOXADDITIONS_x.x.x.x
    where x are any numbers which represent the VirtualBox  version.
Step 3: Mount the cdrom to a folder
  1. Make a new folder where you want to mount the cd. e.g.
    sudo mkdir -p /mnt/cdrom
  2. Type following command to mount the cd to that folder
    sudo mount /dev/disk/by-label/VBOXADDITIONS_x.x.x.x /mnt/cdrom
  3. Now the image is mounted to folder /mnt/cdrom
Step 4: Browse the CD and run the installation script
  1. Browse the cd by going to /mnt/cdrom
    cd /mnt/cdrom
  2. Run the shell script related to the version of linux or windows you are in. for x86 Ubuntu you can run
    sudo ./VBoxLinuxAdditions.run

Here is how I shared MAC OS X folder with Ubuntu Guest OS in VirtualBox

Step 5: Define shared folder
  1. Click Devices on the menu
  2. Click Shared Folders ...
  3. Click + sign
  4. Click Folder Path > Other
  5. Browse the folder and click Choose
  6. Give it a share name e.g.  hostshare
Step 6: Mount the shared folder
  1. Find your userid by typing id in the command prompt of guest
    id
    uid:0(root) gid:0(root) groups:0(root).
    You need uid of the user account for you to be able to write to the mounted folder. Here uid is 0 for root. It might be different for your case.
  2. Mount the share by following command
    sudo mount -t <type> -o <share name> <path where it is to be mounted> e.g.
    sudo mount -t vboxsf -o uid=0 hostshare /mnt/share
    The /mnt/share folder must be present before above command is executed.
  3. Now you can browse the files in that folder.
  4. Optionally you can mount it automatically by adding following line to the file /etc/fstab
    <sharename> <mount folder> vboxsf uid=0,gid=0 0 0 (with your uid and gid) e.g.
    hostshare /mnt/share vboxsf uid=0,gid=0 0 0
    The values of uid and gid can be found by executing the id command as described above.

The methods described above can be used to share MAC OS X file and folder with any Linux/Unix distributions.

Mount Disk on Linux or MAC OS X

When I was new to linux I was unable to mount cd drives on command line interface. Some distributions of Graphical interface didn't mount it automatically. So here is information how we can do it easily.

First insert the cdrom. It generally appears in /dev/cdrom. If you cannot find it you can find it in /dev/disk/by-label/<cdrom label>
sudo -i 
This line promotes us to root. If this line is not executed, we have to type sudo in front of every command and might need to enter password every time.

Make sure that the folder where the cd is to be mounted (/mnt/cdrom in our case) is present. If not present type
mkdir -p /mnt/cdrom
The -p switch makes it sure that all folders get created if it does not exist.

For mounting, type following command to the prompt
mount <path to cd> <Path where it is to be mounted>
For an example
mount /dev/cdrom /mnt/cdrom

Now, the cd image is mounted to /mnt/cdrom. You can browse it by going to the folder /mnt/cdrom
cd /mnt/cdrom

Enjoy!