Mounting a XenServer VHD in Linux



Overview on Getting and Mounting a VHD in Linux

Virtualization is many things, but one thing that it is not is unbreakable. Things happen and if it can happen it is going to happen at the worst possible moment. Read Murphy's Law.

One cool thing with the Rackspace Cloud is that you have the ability to take an "On-Demand" snapshot of an instance at anytime. While this is a cool feature it does have its limitations. Additionally, images can have issues that could prevent them from building correctly when using the normal build process. In these circumstances it may be necessary to download an available image snapshot of a particular instance, mount the VHD file and retrieve the valuable data from the snapshot.

Background :

In the modern Rackspace Cloud, Instance Snapshots, both on-demand and scheduled images, are saved in cloud files. These snapshots are nothing more than clones of the operational VHD that have been compressed and made available to build from. Traditionally speaking, mounting/accessing content stored within a VHD is not possible on a system that does not run your flavor of virtualization. However, in this post I will show you how to locally mount a VHD, with minimal effort using a utility originally developed for Virtualbox Open Source Edition.

A VHD is a Virtual Disk Image that was originally created by Connectix which was acquired by Micro$oft and has since been available to third parties under the Microsoft Open Specification Promise. You can read more about VHD's Here.

Why :
The question that anyone who is anyone who is doing anything worth while must ask. The underlying purpose here that I am sharing was founded by need to recover content that was lost due an image being saved that had been created without the necessary instructions to allow it to build in the traditional sense. Essentially the user had made a change to the running instance and performed a snapshot. Unfortunately, the changes created a situation where the snapshot was no longer able to be used for disaster recovery and or building new instances. Then disaster struck...

My Working Environment

For this post I will be using a Ubuntu 12.04 Insactance running on the Rackspace Cloud. However this could be done on Suse, Debian, CentOS, RedHat, or any other flavor of Linux. If you are using something other than Ubuntu/Debian, you will simply have to change the package management system that you are using in order to get the prerequisites.

Rackspace Open Cloud Server
  • OS = Ubuntu 12.04 LTS
  • RAM = 1 GB

Installing the Packages

The magic behind this WHOLE process is a little known package called vdfuse. This application should be available in MOST major repositories. In Debian/Ubuntu here is how you would get it.

apt-get install virtualbox-fuse

Now that everything is installed you will need to make one configuration change so that all actions done with the virtualbox-fuse utilities are accessible by everyone.

echo 'user_allow_other' >> /etc/fuse.conf

How to get your VHD

Getting the VHD from cloud files is easy. All you have to do is use curl. If your system does not have curl, install it.

To begin we have to authenticate against the API. This will give us our storage URL as well as the token for accessing the Account. Here is a simple curl statement for authenticating against the Rackspace Cloud API.

curl -D - -H "X-Auth-User: <YOUR-USERNAME>" -H "X-Auth-Key: <YOUR-API-KEY>" https://auth.api.rackspacecloud.com/v1.0

This Authentication method will produce the service catalog. From the service catalog you will be using the token and the storage URL. With these two pieces of information we will be making our second curl statement to choose the image file that we want to download. One the statement has been executed you will see a list of all of the images that you have stored in your cloud files account in the "cloudservers" storage container..

curl -D - -H "X-Auth-Token: <YOUR-API-TOKEN>" https://storage101.DC.clouddrive.com/v1/MossoCloudFS_12345-1234-1234-1234-1234567890/cloudservers/

Once you have identified the Image file that want to download, simply get it.

curl -D - -O -H "X-Auth-Token: <YOUR-API-TOKEN>" https://storage101.DC.clouddrive.com/v1/MossoCloudFS_12345-1234-1234-1234-1234567890/cloudservers/ImageFileForSomeServer.tar.gz.0

You should note that downloading could take a long while and before you get the image file you should ensure that your instance has enough free space to accommodate downloading the image file(s); yes I said file(s), you could have up to five, compressed files that represent a single snapshot of a particular instance. Additionally, each file could be potentially 5GB in total size resulting in a max size 25GB while compressed.

If you have multiple Image files that are all part of the same snapshot you will have to catenate the files into a single file.

cat ImageFileForSomeServer.tar.gz.* > NewImageFileForSomeServer.tar.gz

How to access the content of a VHD in Linux

Now that you have the image file, you will need to extract the compressed image file to reveal the actual VHD. This is done by using your favorite archiving tool, in my case I will be using tar.

tar -czf NewImageFileForSomeServer.tar.gz

The extraction may take a minute or ten, depending on how big the image file is. Once you have uncompressed the file, you will have an "image" directory, when you go into this directory, you will see several files. The file that we are interested in is "image.vhd". With that file you will use your new virtualbox-fuse utility to mount that file.

To use the virtualbox-fuse utility you will need to have a mount point for it. In this case I simply create a new directory in the images directory.

mkdir vdmount

Now I run the "vdfuse" command and mount the "image.vhd" file to the "vdmount" directory.

vdfuse -a -f image.vhd vdmount/

Once you have executed this command you will have a "fuse" type file system mounted. You can check this with the "mount" command which will reveal something like this :

image.vhd on /home/kevin/temp/image/vdmount type fuse.vdfuse (rw,nosuid,nodev,allow_other)

now enter the mounted directory.

cd vdmount

In this directory you will see a couple files, the one that we are interested in is "Partition1". Please note, if you had multiple partitions they would be represented by PartitionX, where X is a number. Now we are going to mount the "Partition1" file to another directory, though we are going to do it as a "loop" file with the standard "mount" command.

mount -o loop Partition1 /mnt

Executing this command can also be checked with the mount command, and will provide you a mount point that looks like this :

/home/kevin/temp/image/vdmount/Partition1 on /mnt type ext3 (rw)

Now all you have to do is go to /mnt and start performing your operation. Your entire file system, as it was when the image was taken, is now mounted.

cd /mnt

I hope you enjoyed this post, drop me a line if you have questions.

Comments !


Fork me on GitHub